MySQL:每行返回几个项目的计数
Posted
技术标签:
【中文标题】MySQL:每行返回几个项目的计数【英文标题】:MySQL: return count of several items for each row 【发布时间】:2021-02-12 02:10:35 【问题描述】:我有一张列出一些项目的表格。 然后我有 3 个不同的表,每个表都记录了针对某个项目执行的各种操作,以及日期和执行者:
Table "items":
item_id, title, description
Table "item_views":
item_id, date, user_id
Table "item_follows":
item_id, date, user_id
Table "item_likes":
item_id, date, user_id
我正在尝试提出一个查询,该查询将列出每个项目,以及它们在其他 3 个表中的每个表中被引用的次数。
它只需要计算两个给定日期之间的操作,我还需要能够按任何计数器排序。
所以我会给它两个日期并说“按喜欢排序”,它会返回如下内容:
item id item title views_counter follows_counter likes_counter
item1 Some title 0 5 6
item2 Some title 4 0 4
item3 Some title 3 2 0
任何建议将不胜感激,在此先感谢!
【问题讨论】:
【参考方案1】:对找到计数的子查询使用左连接:
SELECT
i.item_id,
i.title,
COALESCE(v.view_cnt, 0) AS views_counter,
COALESCE(f.follow_cnt, 0) AS follows_counter,
COALESCE(l.like_cnt, 0) AS likes_counter
FROM items i
LEFT JOIN
(
SELECT item_id, COUNT(*) AS view_cnt
FROM item_views
GROUP BY item_id
) v
ON v.item_id = i.item_id
LEFT JOIN
(
SELECT item_id, COUNT(*) AS follow_cnt
FROM item_follows
GROUP BY item_id
) f
ON f.item_id = i.item_id
LEFT JOIN
(
SELECT item_id, COUNT(*) AS like_cnt
FROM item_likes
GROUP BY item_id
) l
ON l.item_id = i.item_id
【讨论】:
非常感谢,这正是我想要的!它也让我可以灵活地添加各种其他过滤和排序。【参考方案2】:您可以使用union all
和聚合:
select i.*,
sum(which = 'view') as views,
sum(which = 'follow') as follows,
sum(which = 'like') as likes
from items i left join
((select item_id, 'view' as which
from item_views
) union all
(select item_id, 'follow' as which
from item_follows
) union all
(select item_id, 'like' as which
from item_likes
)
) vfl
on i.item_id = vfl.item_id
group by i.item_id;
【讨论】:
呃,左加入多个嵌套组比 IMO 好得多 @charlieface 为什么? @Strawberry 诚然,我不太了解 mysql 优化器的工作原理,但 SQL Server 会遇到困难。它可能会在连接之前联合表,和/或强制嵌套循环(与散列或合并相反),而另一个答案中的左连接语法不会有同样的问题。再加上它在美学上对我来说看起来不太好(个人意见) @Charlieface 。 . .你的评论绝对不是真的。事实上,如果外部查询在子查询中的列上进行过滤,SQL Server 与这个union all
版本一起工作得更好。优化器足够聪明,可以将过滤器投射到子查询中在执行union all
。
通常是的,它会将谓词下推,但它也可以用左连接/分组语法做同样的事情,IME 语法更容易被优化器转换。求和在这里的性能也较低,因为您需要检查每一行将其添加到哪个总和,而左连接将求和推到连接下方。您可能仍然可以通过在每个联合表中进行分组来优化您的版本。以上是关于MySQL:每行返回几个项目的计数的主要内容,如果未能解决你的问题,请参考以下文章