MySQL多个左连接

70
我正在尝试为我正在开发的网站创建一个新闻页面。我决定使用正确的MySQL查询(即COUNT(id)和联接,而不是多个查询或num_rows)。我正在使用一个PDO包装器,这应该很好地运行,但当直接通过MySQL CLI应用程序运行时仍然失败。
基本上,我有3个表。一个保存新闻,一个保存评论,另一个保存用户。我的目的是创建一个页面,显示所有(稍后将分页)新闻文章的标题、正文、作者和日期。当我使用第二个查询来获取用户名时,这个工作很好,但后来我决定我宁愿使用JOIN。
那么问题是什么?嗯,我需要两个联接。其中一个是获取作者的用户名,另一个是获取评论数。当我仅仅获取作者的用户名时,所有的结果都符合预期。所有的新闻表中的行(共有2个)都被显示。然而,当我添加了这第二个LEFT JOIN来获取评论行时,我只收到一行新闻(请记住,有2个),而COUNT(comments.id)给我2(它应该显示1,因为每篇文章都有一条评论)。
我做错了什么?为什么它只显示一篇新闻文章,并说它有两条评论,而实际上有两篇新闻文章,每篇文章都有一条评论?
SELECT news.id, users.username, news.title, news.date, news.body, COUNT(comments.id)
FROM news
LEFT JOIN users
ON news.user_id = users.id
LEFT JOIN comments
ON comments.news_id = news.id

还有,只是为了确认另一件事情,我的comments左连接是获取所有帖子的正确方法,无论它们是否有评论,对吗?或者应该使用右连接?哦,最后一件事…如果我将comments.news_id = news.id切换为news.id = comments.news_id,则会得到0个结果。

2个回答

125
你缺少了一个GROUP BY子句:
SELECT news.id, users.username, news.title, news.date, news.body, COUNT(comments.id)
FROM news
LEFT JOIN users
ON news.user_id = users.id
LEFT JOIN comments
ON comments.news_id = news.id
GROUP BY news.id

左连接是正确的。如果你使用内连接或右连接,那么你将无法获取没有评论的新闻项。


1
你必须使用Group By吗?我的新手双重连接不起作用,我正在努力找出原因。 - Joshua Dance
谢谢 - 它帮助我解决了一个难题,这个问题让我花费了3个小时,但现在只用了几分钟就解决了。 - Muhammad

8
为了显示每个新闻标题的所有细节,即主键"news.id",您需要使用GROUP BY子句来对"news.id"进行分组。
SELECT news.id, users.username, news.title, news.date,
       news.body, COUNT(comments.id)
FROM news
LEFT JOIN users
ON news.user_id = users.id
LEFT JOIN comments
ON comments.news_id = news.id
GROUP BY news.id

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接