如何根据MySQL中关联的表行数返回行?

时间:2015-05-21 16:56:47

标签: mysql

如果我有一个帖子表和一个与之关联的评论表。我可以根据单个查询中的评论计数来获取Post列表吗?即我只想要一个包含2条或更多评论的帖子列表。

我知道这不起作用,但它说明了我想做的事。

SELECT * FROM posts p LEFT JOIN comments c ON c.post_id == p.id WHERE COUNT(c) > 2

POSTS
| id | title                 |
------------------------------
| 1  | Post with 1 comment   |
| 2  | Post with 3 comments  |
| 3  | Post with 4 comments  |
| 4  | Post with 0 comments  |

COMMENTS
| id | comment    | post_id  |
------------------------------
| 1  | Hello ...  | 1        |
| 2  | Good ...   | 2        |
| 3  | Hi ...     | 2        |
| 4  | Yes ...    | 2        |
| 5  | Good ...   | 3        |
| 6  | Hi ...     | 3        |
| 7  | Yes ...    | 3        |
… and so forth …

2 个答案:

答案 0 :(得分:2)

您的查询不起作用的原因是因为HAVING子句用于有关聚合的条件。您不能使用WHERE子句。引用链接页面:

  

HAVING子句已添加到SQL,因为WHERE关键字不能   与聚合函数一起使用。

尝试以下查询:

SELECT p.*
FROM posts p
LEFT JOIN comments c ON c.post_id = p.id
GROUP BY p.id
HAVING COUNT(*) > 2;

另请注意,由于您要预先形成聚合,因此需要GROUP BY post_id,因此您会看到每个帖子的结果行。

我还想指出,通过这样分组并且每个帖子只收到一行,您将无法正确显示评论信息。如果您希望查看包含两条以上评论的所有帖子的评论,则需要将上述查询与评论表一起加入:

SELECT c.*
FROM comments c
JOIN(
  SELECT p.id
  FROM posts p
  LEFT JOIN comments c ON c.post_id = p.id
  GROUP BY p.id
  HAVING COUNT(*) > 2) p ON p.id = c.post_id;

以下是SQL Fiddle示例。

修改

如果要搜索具有两个以上评论的帖子,其中一个来自特定用户,则可以使用聚合调整内部查询。您可以在HAVING子句中添加额外条件,以检查SUM(user_id = 1)是否大于0.试试这个:

SELECT p.*
FROM posts p
LEFT JOIN comments c ON c.post_id = p.id
GROUP BY p.id
HAVING COUNT(*) > 2 AND SUM(c.user_id = 1) > 0;

这是更新的SQL fiddle。我调整了您的示例数据,其中user_id 1仅对某个帖子发表了评论,因此您可以看到它确实只是返回的帖子。

答案 1 :(得分:1)

你不能在SUM, MIN, MAX, COUNT etc子句中放置带有WHERE等聚合函数的条件。在设置HAVING语句后,应在GROUP BY子句中添加此类条件。

这意味着WHERE对从数据库中提取的每条记录执行(对于一条记录MIN, MAX, COUNT etc没有意义),并且HAVING对您要求的每个组行执行。

SELECT p.*, COUNT(*) 
FROM posts p 
LEFT JOIN comments c 
ON c.post_id = p.id 
GROUP BY p.id
HAVING COUNT(c.id) > 2