在网页上,我显示了一些图片集(我展示了每个集合的缩略图)。每张图片都有五个相关表格:
喜欢(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等之间挣扎。我相信我有很多方法可以做到这个效率非常低,所以我我希望你能告诉我最好/最快/最有效的方法。
提前致谢!
答案 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
表中每个记录的每个表中的每条记录;如果likes
,views
或comments
中没有记录,则计数将分别为零。
当然,您可以扩展这个集合的想法:
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的查询优化器在每种情况下的智能程度。)