我有一个包含2个表的数据库:
用户(user_id主键)和朋友
friends表被组织成2列friend1,friend2,两列都包含user_ids(引用用户的外键)。在每个朋友对中,friend1的用户ID小于朋友2的用户ID。
我正在尝试查找不是朋友但分享最多朋友的用户列表。
我设法在两个单独的查询中执行此操作:
用户u1和u2的共享好友数
select count(*)
from
((select friend1 from friends where friend2 = u1 UNION
select friend2 from friends where friend1 = u1)
INTERSECT
(select friend1 from friends where friend2 = u2 UNION
select friend2 from friends where friend1 = u2))
;
所有user_id的设置 - >不是朋友的user_id对:
select distinct
u1.user_id as friend1,
u2.user_id as friend2
from
users u1,
users u2
where
u1.user_id < u2.user_id
minus
select friend1, friend2
from friends order by friend1;
然而,我的最终目标是获得
的结果user1 user2 shared_friends
使得user1&lt; user2,user1和user2不是朋友,shared_friends是这些用户共有多少朋友的计数,到目前为止我没有成功。
答案 0 :(得分:0)
这应该让你入门,但它是Microsoft SQL(虽然非常通用)
select a1.friend1 as User1,
a2.friend1 as user2,
count( distinct a1.friend2) as Shared_Friends
from friends a1
join (select distinct friend1,friend2 from friends a2) a2
on a1.friend2=a2.friend2
left join friends a3 on a3.friend1=a1.friend1 and a3.friend2 = a2.friend1
where (a1.friend1=1 and a2.friend1=8) and a3.friend1 is null
group by a1.friend1,a2.friend1
答案 1 :(得分:0)
CTE只是提供一些样本数据。
With Users As
(
Select 1 As UserId, 'Alice' As Name
Union All Select 2, 'Bob'
Union All Select 3, 'Caroline'
Union All Select 4, 'Doug'
)
, Friends As
(
Select 1 As Friend1, 2 As Friend2
Union All Select 2, 1
Union All Select 2, 3
Union All Select 2, 4
Union All Select 3, 1
Union All Select 3, 4
)
, UserFriends As
(
Select U1.UserId
, Case
When F1.Friend1 = U1.UserId Then F1.Friend2
Else F1.Friend1
End As Friend
From Users As U1
Join Friends As F1
On U1.UserId In(F1.Friend1,F1.Friend2)
Group By U1.UserId
, Case
When F1.Friend1 = U1.UserId Then F1.Friend2
Else F1.Friend1
End
)
Select U1.Name, U2.Name
, Count(*) As MutualFriendCount
, Group_Concat(F.Name) As SharedFriends
From UserFriends As UF1
Join UserFriends As UF2
On UF2.Friend = UF1.Friend
Join Users As U1
On U1.UserId = UF1.UserId
Join Users As U2
On U2.UserId = UF2.UserId
Join Users As F
On F.UserId = UF1.Friend
And F.UserId = UF2.Friend
Where UF1.UserId <> UF2.UserId
And Not Exists (
Select 1
From UserFriends As F3
Where F3.UserId = UF1.UserId
And F3.Friend = UF2.UserId
)
Group By U1.Name, U2.Name
Order By U1.Name, U2.Name