同一张表上的多个连接,在一个查询中计数
Posted
技术标签:
【中文标题】同一张表上的多个连接,在一个查询中计数【英文标题】:Multiple joins on the same table with counting in one query 【发布时间】:2015-09-10 22:56:22 【问题描述】:我有一个关于两次加入同一个表的 SQL 查询的基本问题。这听起来很简单,但我有一些麻烦。我希望,任何人都可以帮助我解决这个问题:)
我有两个小表:“peoples”(列:id、name、...)和“likes”(id、who、whom)。人们可以互相设置“喜欢”。这种关系是多对多的。 我想得到人们喜欢的桌子:收到的“喜欢”的数量,交付的数量和相互喜欢的数量。 当我只使用一个连接时,一切都是正确的。但是对于两个连接(或更多),mysql 合并所有行(如预期的那样)并且我得到错误的计数值。我不知道,在这种情况下我必须如何使用 count/sum/group-by 运算符:( 我想在一个查询中不使用子查询。
我使用了这样的查询:
SELECT *, count(l1.whom), count(l2.whom)
FROM people p
LEFT JOIN likes l1 ON l1.who = p.id
LEFT JOIN likes l2 ON l2.whom = p.id
GROUP BY p.id;
SELECT p.id, name,
count(lwho.who) delivered_likes,
count(lwhom.whom) received_likes,
count(lmut.who) mutual_likes
FROM people AS p
LEFT JOIN likes AS lwho ON p.id = lwho.who
LEFT JOIN likes AS lwhom ON lwhom.id = lwho.id
LEFT JOIN likes AS lmut ON lwhom.who = lmut.whom AND lwhom.whom = lmut.who
GROUP BY p.id;
但它计算的点赞数不正确。
这只是训练的问题,性能并不重要,但我想,我上次查询中的三个连接太多了。我可以使用 2 个连接吗?
提前感谢您的帮助。
【问题讨论】:
您的加入看起来不错。但是,您应该确保按查询中未聚合的所有列进行分组。您没有在第二个查询中按name
分组。我无法忍受 MySQL 允许这样做。
【参考方案1】:
我推测people
和likes
之间存在1:N的关系。
据我所知,第二个查询的一个问题是likes
的lwhom
相关性通过id=id
连接到lwho
。基本上lwhom
是 lwho
。我建议将此关联的 ON 子句从 lwhom.id = lwho.id
更改为 p.id = lwhom.whom
。
但是,计数仍会受到 JOIN 的影响。但是,假设您在 likes
表中有一个 ID 列,那么您可以让每个 COUNT
计算每个人的不同 Like ID - 如果没有,请考虑只使用 COUNT(DISTINCT correlation.*)
。
抛开题外话,以下应该可以工作:
SELECT p.id, name,
count(distinct lwho.id) delivered_likes,
count(distinct lwhom.id) received_likes,
count(distinct lmut.id) mutual_likes
FROM people AS p
LEFT JOIN likes AS lwho ON p.id = lwho.who
LEFT JOIN likes AS lwhom ON p.id = lwhom.whom
LEFT JOIN likes AS lmut ON lwhom.who = lmut.whom AND lwhom.whom = lmut.who
GROUP BY p.id,p.name;
我有一个 SQL Fiddle here。
【讨论】:
嗨,亚当。非常感谢您的回答和示例。它也适用于我。它帮助我理解我的错误。应该小心几个连接和分组:) PS 当然,关系是 1:N - 一个人和更多的喜欢。这是我在描述中的可悲错误。以上是关于同一张表上的多个连接,在一个查询中计数的主要内容,如果未能解决你的问题,请参考以下文章