SQL 选择好友查询

Posted

技术标签:

【中文标题】SQL 选择好友查询【英文标题】:SQL Select friends query 【发布时间】:2015-06-08 23:58:35 【问题描述】:

我正在尝试选择当前用户的朋友,使用的查询返回每个友谊表 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 的朋友列表。

我希望我有道理,谢谢!

【问题讨论】:

【参考方案1】:

工会怎么样? http://sqlfiddle.com/#!9/da447/7

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*

【讨论】:

【参考方案2】:

为什么不简单呢?除非您需要来自用户的字段,但您没有指明。

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

【讨论】:

我可能是错的,但他似乎试图获取当前用户所有朋友的姓名 @BarbaraLaird:当然可以,但并不明确。如果是这样,显然需要你建议的更多。【参考方案3】:

首先在从右表过滤时执行left join 是无稽之谈,因为左连接变成了内连接。其次,你可以通过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

【讨论】:

以上是关于SQL 选择好友查询的主要内容,如果未能解决你的问题,请参考以下文章

练习题:选择器和选择好友

在选择 sql 查询中选择

同桌选择好友请求

如何限制 FBFriendPicker 中的好友选择?

更快的选择最大 SQL 查询

如何将任何给定的 SQL/HQL 选择查询动态转换为等效计数查询?