在同一个 table 上进行多个连接,并在一个查询中计数

Multiple joins on the same table with counting in one query

我有一个关于 SQL 查询的基本问题,其中加入了相同的 table 两次。这听起来很简单,但我遇到了一些麻烦。我希望,任何人都可以帮助我解决这个问题:)

我有两个小 table:"peoples"(列:id、name、...)和 "likes"(id、who、whom)。人们可以互相设置 "likes"。这种关系是多对多的。 我想要获得 table 的人喜欢:收到的计数 "likes"、已发送的计数和相互喜欢的计数。 当我只使用一个连接时,一切都是正确的。但是对于两个连接(或更多)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 个连接来完成吗?

在此先感谢您的帮助。

我推测 peoplelikes 之间存在 1:N 关系。

据我所知,你的第二个查询的一个问题是 likeslwhom 相关性通过 id=id 连接到 lwho。基本上lwhom就是lwho。我建议将此关联的 ON 子句从 lwhom.id = lwho.id 更改为 p.id = lwhom.whom.

但是,计数仍会受到 JOIN 的影响。假设您在 likes table 中有一个 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.