我正在尝试打印20个在线博客文章的列表,以及每篇文章的评论,照片和视频的数量。他们都共享article_id
字段,但不是每篇文章都有评论,照片或视频。
到目前为止我的工作查询(没有计数)
SELECT a.article_id, a.title, a.published, a.description, a.status, ad.firstname, ad.lastname FROM blog_articles AS a
LEFT JOIN admins AS ad ON a.author_id = ad.admin_id *** grabs article author
WHERE a.status = 'Online' ORDER BY a.published DESC LIMIT 0, 20
我的尝试(带计数)
SELECT COUNT(comment_id) AS tot_comments, COUNT(photo_id) AS tot_photos,
COUNT(video_id) AS tot_videos, a.article_id, a.title, a.published, a.description,
a.status, ad.firstname, ad.lastname
FROM blog_articles AS a
LEFT JOIN blog_comments AS ac USING (article_id)
LEFT JOIN photos AS p USING (article_id)
LEFT JOIN videos AS v USING (article_id)
LEFT JOIN admins AS ad ON a.author_id = ad.admin_id
WHERE a.status = 'Online'
GROUP BY a.article_id
ORDER BY a.published DESC LIMIT 0, 20
但这很奇怪。我收到了正确的文章和文字数据,但计算结果是合理的!如果一篇文章真的有18条评论,0张照片和1个视频,我显示的结果显示18条评论,0张照片和18个视频。如果一篇文章有0条评论,6张照片和1个视频,我的结果是0条评论,6张照片和6个视频!
我接近它的工作,我的加入知识生锈,我的大脑疼,请有人能让我摆脱痛苦并踢我终点线?我可以看到发生了什么,但我无法解决如何解决它。
这是我想在blog_articles
表中为每条记录显示的内容:
文章标题:这是标题| 评论: 42 | 照片: 20 | 视频 2
答案 0 :(得分:4)
我认为你最好的选择是派生表
SELECT a.title, c.cnt as comments, p.cnt as photos, v.cnt as videos
FROM blog_articles a
INNER JOIN admins ad
ON a.author_id = ad.admin_id
LEFT OUTER JOIN (
SELECT article_id, COUNT(comment_id) as cnt
FROM blog_comments
GROUP BY article_id) c
ON a.article_id = c.article_id
LEFT OUTER JOIN (
SELECT article_id, COUNT(photo_id) as cnt
FROM photos
GROUP BY article_id) p
ON a.article_id = p.article_id
LEFT OUTER JOIN (
SELECT article_id, COUNT(video_id) as cnt
FROM videos
GROUP BY article_id) v
ON a.article_id = v.article_id
WHERE a.status = 'Online'
GROUP BY a.article_id
ORDER BY a.published DESC LIMIT 0, 20
仅仅因为我无法放手,请查看this SQL Fiddle,其中显示了派生表和计数不同选项的执行计划和时间。两者都提供相同的数据,但在此示例中,派生表为0ms,而计数为1ms。看到这些查询使用一些真实数据执行会很有趣,但根据我的经验,派生表会产生计数不能的性能。
答案 1 :(得分:2)
没试过,但请尝试
SELECT COUNT(comment_id) AS tot_comments, COUNT(photo_id) AS tot_photos,
COUNT(video_id) AS tot_videos, a.article_id, a.title, a.published, a.description,
a.status, ad.firstname, ad.lastname
FROM blog_articles AS a
LEFT JOIN blog_comments AS ac ON ac.article_id = a.article_id
LEFT JOIN photos AS p ON p.article_id = a.article_id
LEFT JOIN videos AS v ON v.article_id = a.article_id
LEFT JOIN admins AS ad ON a.author_id = ad.admin_id
WHERE a.status = 'Online'
GROUP BY a.article_id
ORDER BY a.published DESC LIMIT 0, 20