2

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

喜欢(id,user_id,picture_id),
视图(id,user_id,picture_id),
评论(id,user_id,picture_id,comment),

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

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

所以基本上:计算每张图片的喜欢,将它们全部计数,显示数字。计算每张图片的浏览量,将它们全部计数,显示数字。统计每张图片的评论,全部统计,显示数字。然后冲洗并重复所有收集。

我是 mysql 的新手,我在选择、多个连接、计数、php 与 mysql 等之间苦苦挣扎。我敢肯定有很多方法可以做到这一点,但效率很低,所以我希望你可以告诉我最好/最快/最有效的方法。

提前致谢!

4

2 回答 2

3

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

由于您将计算每个表上的条目 every 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

基本上,您正在为表中的每条记录计算每个表中的每条记录pictureslikes如果,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 byaValue你要检索的集合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

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

于 2013-01-08T08:04:06.327 回答
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来优化它。但是,我应该注意,我实际上并没有测试过这个查询。我也不知道这在性能方面如何与 Barranka 的LEFT JOIN解决方案进行比较。(如果天真地实现,两者都会非常糟糕,所以归结为 MySQL 的查询优化器在每种情况下的智能程度。)

于 2013-01-08T08:06:03.827 回答