我试图弄清楚如何为SQL Server编写一个用于匹配朋友的查询。名称在同一个表中的两列中。只有“接受”的朋友才能归还。
以下是数据库信息的示例:
ID Name_1 Name_2 Accepted
=====================================
1 Jimmy John 1
2 John Joey 1
3 Joey Jimmy 1
4 John Sally 1
5 Jimmy Sally 0
在这个例子中,吉米是约翰的朋友。这两者之间的共同朋友(和期望的结果)是乔伊。莎莉也很常见,但吉米还没有接受她作为朋友。
答案 0 :(得分:3)
尝试使用这种双重自我加入来实现相互友谊:
SELECT Friend_1, Friend_2, COMMON
FROM
(
SELECT f2.NAME_1 AS Friend_1
,f1.NAME_2 AS Friend_2
,f2.Name_2 AS COMMON
FROM friends f1
INNER JOIN friends f2
ON f1.NAME_1 = f2.NAME_2
WHERE f1.accepted = 1 AND f2.accepted = 1
) T
INNER JOIN FRIENDS F3
ON (F3.Name_1 = Friend_1 AND F3.Name_2 = Friend_2)
OR (F3.Name_2 = Friend_1 AND F3.Name_1 = Friend_2)
WHERE F3.ACCEPTED <> 0 AND Friend_1 = 'John' AND Friend_2 = 'Jimmy'
COMMON是常见的朋友。
注意:我不确定这种结构是保持这种关系的最佳结构,你有相互友谊的规则,关于友谊的拒绝,但看起来你对此一无所知这些信息。您是否只知道部分信息或这是您的存储系统/架构?
答案 1 :(得分:0)
看起来不那么优雅但可能性能更好的解决方案可能是:
DECLARE @person1 VARCHAR(50) = 'Jimmy'
DECLARE @person2 VARCHAR(50) = 'John'
SELECT FriendsOfP1.Name as MutualFriend
FROM ( SELECT A.name_2 AS Name
FROM friends A
WHERE ( A.name_1 = @person1 )
AND Accepted = 1
AND name_2 <> @person2
UNION ALL
SELECT A.name_1
FROM friends A
WHERE ( A.name_2 = @person1 )
AND Accepted = 1
AND name_1 <> @person2 ) AS friendsOfP1
INNER JOIN ( SELECT A.name_2 AS Name
FROM friends A
WHERE ( A.name_1 = @person2 )
AND Accepted = 1
AND name_2 <> @person1
UNION ALL
SELECT A.name_1
FROM friends A
WHERE ( A.name_2 = @person2 )
AND Accepted = 1
AND name_1 <> @person1 ) AS FriendsOfP2
ON FriendsOfP1.Name = FriendsOfP2.Name