如何从多个表中获取多个计数?

时间:2013-01-08 07:36:42

标签: php mysql sql

在网页上,我显示了一些图片集(我展示了每个集合的缩略图)。每张图片都有五个相关表格:

  

喜欢(id,user_id,picture_id),
  观看次数(id,user_id,picture_id),
  评论(id,user_id,picture_id,评论),

     

图片(id(等于前面表格中的“picture_id”),collection_id,picture_url和其他几列),
  集合(id(等于上表中的collection_id)和其他几列。

加载我的页面时,我需要汇总每个集合中所有图片的喜欢,观看和评论的数量,以便在每个集合下显示这些数字。

所以基本上:计算每张图片的喜好,统计它们,显示数字。计算每张图片的视图,统计它们,显示数字。计算每张图片的评论,统计它们,显示数字。然后冲洗并重复所有系列。

我是mysql的新手,我在选择,多连接,计数,php与mysql等之间挣扎。我相信我有很多方法可以做到这个效率非常低,所以我我希望你能告诉我最好/最快/最有效的方法。

提前致谢!

2 个答案:

答案 0 :(得分:3)

您可以使用选择和左连接来解决此问题。

由于您将为每个pictureId计算每个表上的条目,因此您的pictures表将是每个关系的左侧。所以:

select 
    p.id as pictureId,
    count(distinct l.id) as count_likes,
    count(distinct v.id) as count_views,
    count(distinct c.id) as count_comments
from
    pictures as p
    left join likes as l on p.id = l.pictureId
    left join views as v on p.id = v.pictureId
    left join comments as c on p.id = c.pictureId
group by
    p.id

基本上,您正在计算pictures表中每个记录的每个表中的每条记录;如果likesviewscomments中没有记录,则计数将分别为零。

当然,您可以扩展这个集合的想法:

select
    c.id as collection_id,
    p.id as picture_id,
    count(distinct l.id) as count_likes,
    count(distinct v.id) as count_views,
    count(distinct c.id) as count_comments
from
    collections as c
    left join pictures as p on c.id = p.collection_id
    left join likes as l on p.id = l.picture_Id
    left join views as v on p.id = v.picture_Id
    left join comments as c on p.id = c.picture_Id
group by
    c.id,
    p.id

如果您要过滤每个集合的结果,只需在where c.id = aValue之前添加group by(其中aValue是您要检索的集合ID)

希望这会对你有所帮助。


如果您只需要每个集合的汇总数据:

select
    c.id as collection_id,
    count(distinct l.id) as count_likes,
    count(distinct v.id) as count_views,
    count(distinct c.id) as count_comments
from
    collections as c
    left join pictures as p on c.id = p.collection_id
    left join likes as l on p.id = l.picture_Id
    left join views as v on p.id = v.picture_Id
    left join comments as c on p.id = c.picture_Id
group by
    c.id

这应该可以解决问题; - )

答案 1 :(得分:0)

您可以使用子选择执行此操作:

SELECT
  collections.*,
  ( SELECT COUNT(*) FROM pictures, likes
    WHERE pictures.id = likes.picture_id
      AND pictures.collection_id = collection.id
  ) AS like_count,
  ( SELECT COUNT(*) FROM pictures, views
    WHERE pictures.id = views.picture_id
      AND pictures.collection_id = collection.id
  ) AS view_count,
  ( SELECT COUNT(*) FROM pictures, comments
    WHERE pictures.id = comments.picture_id
      AND pictures.collection_id = collection.id
  ) AS comment_count
FROM collections
WHERE ...

这看起来好像是在pictures表上翻了三次,但我怀疑MySQL可以使用join buffer来优化它。但是我应该注意到,我还没有真正测试过这个查询。我也不知道这与巴兰卡的LEFT JOIN解决方案在性能方面的比较。 (如果天真地实现,两者都会非常糟糕,所以它归结为MySQL的查询优化器在每种情况下的智能程度。)