Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/kubernetes/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何进行这个复杂的查询?_Mysql_Sql_Database - Fatal编程技术网

Mysql 如何进行这个复杂的查询?

Mysql 如何进行这个复杂的查询?,mysql,sql,database,Mysql,Sql,Database,这是我的数据库架构: Post: id title body date Tag: id title Post_Tag: id id_post id_tag Comment: id id_post body date post和tag之间存在多对多关系 我需要在这个主页上打印最近10篇文章: <a href="post.php?id=ID_POST">POST_TITLE</a> POST_BODY <a href="tag.php?id=ID_TAG_1

这是我的数据库架构:

Post:
id
title
body
date

Tag:
id
title

Post_Tag:
id
id_post
id_tag

Comment:
id
id_post
body
date
post和tag之间存在多对多关系

我需要在这个主页上打印最近10篇文章:

<a href="post.php?id=ID_POST">POST_TITLE</a>

POST_BODY

<a href="tag.php?id=ID_TAG_1"> TAG_TITLE_1 </a>
<a href="tag.php?id=ID_TAG_2"> TAG_TITLE_2 </a>
<a href="tag.php?id=ID_TAG_3"> TAG_TITLE_3 </a>

COMMENTS_NUMBER

您可能不希望将此作为单个查询来执行,但理论上您可以这样做

SELECT
    Post.id AS post_id,
    Post.title AS post_title,
    Post.body AS post_body,
    GROUP_CONCAT(CONCAT(Tag.id, "|", Tag.title) SEPARATOR '#') AS tags,
    COUNT(Comment.id) AS comment_count
FROM Post
LEFT JOIN Comment ON Post.id = Comment.id_post
LEFT JOIN Post_Tag ON Post.id = Post_Tag.id_post
LEFT JOIN Tag ON Tag.id = Post_Tag.id_tag
GROUP BY Post.id
ORDER BY Post.date ASC
我没有检查这个,因为我没有访问您的数据的权限,但它应该可以工作。您需要手动拆分标记,该标记将以“ID | TITLE#ID | TITLE”的格式显示,但这是唯一需要的额外处理

或者,您可以通过在两个单独的查询之间拆分此工作负载来避免标记的组_CONCAT:

SELECT
    Post.id AS post_id,
    Post.title AS post_title,
    Post.body AS post_body,
    COUNT(Comment.id) AS comment_count
FROM Post
LEFT JOIN Comment ON Post.id = Comment.id_post
GROUP BY Post.id
ORDER BY Post.date ASC
由此,您将存储所有单个post_ID,并在第二个查询中使用它们,如下所示:

SELECT
    Tag.id,
    Tag.title
FROM Post_Tag
INNER JOIN Tag ON Post_Tag.id_tag = Tag.id
WHERE Post_Tag.id_post IN (**comma-separated list of Post IDs**)

这意味着您可以执行两个查询,否则您必须执行一个查询以获取所有帖子,然后为每个帖子执行另一个查询以检索标签-这是一个N+1查询,而我上面提出的是解决此问题的常用方法。

您可能不希望将此作为单个查询来执行,但理论上您可以这样做

SELECT
    Post.id AS post_id,
    Post.title AS post_title,
    Post.body AS post_body,
    GROUP_CONCAT(CONCAT(Tag.id, "|", Tag.title) SEPARATOR '#') AS tags,
    COUNT(Comment.id) AS comment_count
FROM Post
LEFT JOIN Comment ON Post.id = Comment.id_post
LEFT JOIN Post_Tag ON Post.id = Post_Tag.id_post
LEFT JOIN Tag ON Tag.id = Post_Tag.id_tag
GROUP BY Post.id
ORDER BY Post.date ASC
我没有检查这个,因为我没有访问您的数据的权限,但它应该可以工作。您需要手动拆分标记,该标记将以“ID | TITLE#ID | TITLE”的格式显示,但这是唯一需要的额外处理

或者,您可以通过在两个单独的查询之间拆分此工作负载来避免标记的组_CONCAT:

SELECT
    Post.id AS post_id,
    Post.title AS post_title,
    Post.body AS post_body,
    COUNT(Comment.id) AS comment_count
FROM Post
LEFT JOIN Comment ON Post.id = Comment.id_post
GROUP BY Post.id
ORDER BY Post.date ASC
由此,您将存储所有单个post_ID,并在第二个查询中使用它们,如下所示:

SELECT
    Tag.id,
    Tag.title
FROM Post_Tag
INNER JOIN Tag ON Post_Tag.id_tag = Tag.id
WHERE Post_Tag.id_post IN (**comma-separated list of Post IDs**)

这意味着您可以进行两次查询,否则您必须进行一次查询以获取所有帖子,然后对每个帖子进行另一次查询以检索标签-这是一个N+1查询,而我上面提出的是解决此问题的常用方法。

如果我理解正确,您正在尝试创建一个“带有标签和注释的帖子”系统,具有以下关系


一个查询就可以将它们全部规则化 正如所建议的那样,您应该对标签进行
分组\u CONCAT
,以避免重复帖子。您还必须进行一些次要的后期处理来格式化标记,除非您只需要标记标题,但仅此而已

这里有一个例子

SELECT
    p.ID,
    p.title,
    p.body,
    p.c_date,
    GROUP_CONCAT(DISTINCT CONCAT_WS('|', CAST(t.ID AS CHAR), t.title) SEPARATOR ';') AS tags,
    COUNT(c.ID) AS comments
FROM Post p
    LEFT JOIN Comment c ON p.ID = c.id_post
    LEFT JOIN Post_Tag pt ON p.ID = pt.id_post
    LEFT JOIN Tag t ON pt.id_tag = t.ID
GROUP BY p.ID, p.title, p.body, p.c_date
ORDER BY p.c_date DESC
注意,我对标记id使用显式类型转换


以下是对和的一些参考。

如果我理解正确,您正在尝试创建一个“带有标签和注释的帖子”系统,具有以下关系


一个查询就可以将它们全部规则化 正如所建议的那样,您应该对标签进行
分组\u CONCAT
,以避免重复帖子。您还必须进行一些次要的后期处理来格式化标记,除非您只需要标记标题,但仅此而已

这里有一个例子

SELECT
    p.ID,
    p.title,
    p.body,
    p.c_date,
    GROUP_CONCAT(DISTINCT CONCAT_WS('|', CAST(t.ID AS CHAR), t.title) SEPARATOR ';') AS tags,
    COUNT(c.ID) AS comments
FROM Post p
    LEFT JOIN Comment c ON p.ID = c.id_post
    LEFT JOIN Post_Tag pt ON p.ID = pt.id_post
    LEFT JOIN Tag t ON pt.id_tag = t.ID
GROUP BY p.ID, p.title, p.body, p.c_date
ORDER BY p.c_date DESC
注意,我对标记id使用显式类型转换



以下是对和的一些参考。

请发布您尝试过的内容。然后我们可以从那里开始。我刚刚在问题中插入了我尝试过的:DQ:为什么Post_标记表有ID?您预期的结果是什么?由于单个post有多个标记,post数据将对每个标记重复。post_tag.id用于什么?请发布您尝试过的内容。然后我们可以从那里开始。我刚刚在问题中插入了我尝试过的:DQ:为什么Post_标记表有ID?您预期的结果是什么?因为有多个标签用于单个帖子数据,每个标签都会重复。post_tag.id是什么?所以你认为最好的方法是对每个帖子进行一次查询以获取所有帖子,对每个帖子进行一次查询以获取所有相关联的标签?我刚刚对其进行了测试,在结果的“标签”列中,我得到了如下结果:“[BLOB-38B]”@xRobot这将是一个N+1查询,这是不好的。通常,您会执行一次查询以获取所有帖子(在您的情况下,您可以同时获取评论计数),再执行一次查询以获取第一次查询中找到的每个帖子ID的所有标记。这样可以让事情轻松一点。对不起,我不明白。你认为最好的方法是做一个单一的查询(就像你的答案一样)来获得帖子、评论编号和标签还是N+1查询?我的原始答案应该适用于单一查询;我的首选方法是进行两次查询——一次获取所有帖子,另一次获取每篇帖子的所有相关标签。因此,你认为最好的方法是进行一次查询以获取所有帖子,一次查询以获取所有相关标签?我刚刚对其进行了测试,在结果的“标签”列中,我得到如下结果:[BLOB-38B]“@xRobot这将是一个N+1查询,这是不好的。您通常会执行一个查询来获取所有帖子(在您的情况下,您可以同时获取评论计数),再加上另一个查询,以获取您在第一个查询中找到的每个帖子ID的所有标签。这使事情变得更轻松。对不起,我不明白。您认为最好的方法是执行一个查询(如您的答案中所示)吗要获取帖子、评论编号和标签或N+1查询?我的原始答案应该适用于单个查询;我的首选方法是执行两个查询-一个用于获取所有帖子,另一个用于获取每个帖子的所有相关标签。