SQL Server:在2列中查找共享项

时间:2013-05-31 13:34:02

标签: sql-server

我试图弄清楚如何为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

在这个例子中,吉米是约翰的朋友。这两者之间的共同朋友(和期望的结果)是乔伊。莎莉也很常见,但吉米还没有接受她作为朋友。

2 个答案:

答案 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是常见的朋友。

相关SQL Fiddle

注意:我不确定这种结构是保持这种关系的最佳结构,你有相互友谊的规则,关于友谊的拒绝,但看起来你对此一无所知这些信息。您是否只知道部分信息或这是您的存储系统/架构?

答案 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