我有一个模型,人们可以互相“交友”(友谊)。我如何查询一个人既是朋友又是朋友的人的数量,而不计算两次双向友谊?
这是一个例子:
1 -> 2
2 -> 1
1 -> 3
4 -> 1
我希望将其注册为拥有 3 个朋友的 #1
友谊(id、person_id、friend_id)
Select
count(distinct(f.user_id + f.friend_id))
From
Friends f
Where
f.user_id = 1 or f.friend_id = 1
不过,这样做可能会更有效:
Select
Count(*)
From (
Select friend_id From Friends f Where f.user_id = 1
Union
Select user_id From Friends f where f.friend_id = 1
) as a
为了让每个人的朋友数,假设还有一个 users 表:
Select
u.user_id,
count(distinct f.user_id + f.friend_id)
From
Users u
Left Outer Join
Friends f
On u.user_id = f.user_id Or u.user_id = f.friend_id
尽管使用 or 加入通常意味着查询速度较慢。另一种方法是:
Select
u.user_id,
count(distinct f.friend_id)
From
Users u
Left Outer Join (
Select user_id, friend_id from Friends
Union All
Select friend_id, user_id from Friends
) f
On u.user_id = f.user_id
您可以将 Union All 更改为 Union 并摆脱独特的,不确定哪个会更快。
select person_id, sum(ct) friend_count
from (select person_id, count(*) ct from friends
group by person_id
UNION ALL
select f1.friend_id, count(*) ct
from friends f1
left join friends f2 on f1.person_id = f2.friend_id
where f2.person_id is null
group by f1.friend_id) u
group by person_id
Select distinct f1.id,count(f1.id)
from friendships f1
join friendships f2 on f1.person_id = f2.friend_id
Group by f1.id
select id, count(*)
from
(select id, person_id as p1, friend_id as p2 from friendships
union select id, person_id as p2, friend_id as p1 from friendships) fs
group by id