SQL选择朋友查询

时间:2015-06-08 23:58:36

标签: sql social-networking

我正在尝试选择当前用户的朋友,使用一个查询返回每个友谊的表1行的朋友列表。

我有一个用户和朋友表:

User(UserID, Username)

Friends(IdFirst, IdSecond)

假设我有以下用户:(1, 'Alex'), (2, 'Ana'), (3, 'Daniel')以及以下友情:(1, 2), (1,3), (2,3)

到目前为止,我一直在使用此查询:

SELECT * FROM User U
LEFT JOIN Friends F
ON U.IdUser = F.IdSecond
WHERE F.IdFirst = *LOGGED USER ID*

它只有在我有镜像友谊的情况下才有效,例如:(1, 2) (2, 1) (1, 3) (3,1)我只希望每个友谊都有一对。如果使用上述查询,我​​只会获得IdFirst的朋友列表。

我希望我有意义,谢谢!

3 个答案:

答案 0 :(得分:4)

工会怎么样? fiddle

SELECT * FROM users U
  LEFT JOIN friends F
  ON U.userid = F.idsecond
  WHERE F.idfirst = *LOGGED USER ID*
UNION
SELECT * FROM users U
  LEFT JOIN friends F
  ON U.userid = F.idfirst
  WHERE F.idsecond = *LOGGED USER ID*

答案 1 :(得分:0)

为什么不简单?除非您需要未指明用户的字段。

SELECT idFirst
      ,idSecond 
  FROM Friends
 WHERE IdFirst = *LOGGED USER ID*
    OR IdSecond =*LOGGED USER ID*

这意味着你不必拥有镜像友谊 - 事实上你不应该这样做。

编辑:如果您确实希望用户为朋友,您可以在没有工会的情况下执行此操作:

SELECT * 
  FROM users U
 WHERE UserID <> *LOGGED USER ID*
   AND EXISTS(
               SELECT 1
                 FROM Friends 
                 WHERE (IdFirst = *LOGGED USER ID* AND IdSecond = UserID)
                    OR (IdSecond =*LOGGED USER ID* AND IdFirst = UserID)
             )  

我不确定它比@BarbaraLaird更好。虽然这里的执行计划看起来更简单http://sqlfiddle.com/#!9/da447/13

答案 2 :(得分:0)

首先在从右表过滤时执行left join是无意义的,因为左连接变为内连接。其次,您可以使用连接执行此操作,无需union

select case when u1.Id = @currentUser then u1.Id else u2.Id end as Id,
       case when u1.Id = @currentUser then u1.Name else u2.Name end as Name,
from Friends f
join Users u1 on f.IdFirst u1.Id
join Users u2 on f.IdSecond u2.Id
where u1.Id = @currentUser or u2.Id = @currentUser