选择用户非朋友的MySQL查询

时间:2019-05-22 12:58:09

标签: mysql sql social-network-friendship

我具有以下Mysql数据库架构:

User(Id, FirstName, LastName, NickName, Etc.)
Request(SenderId, ReceiverId)
Friendship(Id1, Id2)

我认为友谊是无方向性的关系,这意味着对于每个友谊,我都会将其两次插入到友谊表中。 (请让我知道这不是一个好主意)。

我要检索的是一个用户列表,这些用户不是特定用户的朋友(我叫他UserX),也没有正在/向他发送当前请求的人。

最初的试验使我想到了这一点

SELECT User.Id, User.NickName, User.Picture FROM User 
LEFT JOIN Friendship A ON User.Id = A.Id1
LEFT JOIN Friendship B ON User.Id = B.Id2 
LEFT JOIN Request C ON User.Id = C.Sender
LEFT JOIN Request D ON User.Id = D.Reciever 
WHERE User.Id <> ? 

当然,占位符是UserX的ID。

这是行不通的,因为尽管消除了与UserX有友谊或要求的元组,但朋友仍然出现是因为他们与其他用户有友谊!

谢谢。

3 个答案:

答案 0 :(得分:1)

使用左联接到联合列表:

select *
from User u1
left join 
    (
    select ID2 as id
    from Friendships
    where ID1 = 'UserX'
    union all
    select ID1
    from Friendships
    where ID2 = 'UserX'
    union all
    select Sender
    from Request 
    where Receiver = 'UserX'
    union all
    select Receiver
    from Request
    where Sender = 'UserX'
    ) ux
on ux.id = u1.id
where ux.id is null
and ux.id <> 'UserX'

答案 1 :(得分:1)

如果您想要有效的解决方案,请多次使用not exists

select u.*
from user u
where not exists (select 1 from friendship f where f.id1 = u.id and f.id2 = ?) and
      not exists (select 1 from friendship f where f.id2 = u.id and f.id1 = ?) and
      not exists (select 1 from request r where r.SenderId = u.id and r.ReceiverId = ?) and
      not exists (select 1 from request r where r.ReceiverId = u.id and r.SenderId = ?);

尤其是,这可以利用以下位置的索引:

  • friendship(id1, id2)
  • friendship(id2, id1)
  • request(SenderId, ReceiverId)
  • request(ReceiverId, SenderId)

union一起子查询的解决方案相比,这应该具有更好的性能。

答案 2 :(得分:0)

What if you collect all distinct IDs from table "request" and "Friendship" and then select records from Users ID not available in the above list.

SELECT Id, FirstName, LastName, NickName
FROM User
WHERE ID NOT IN
(
    SELECT DSTINCT Id1 ID FROM Friendship
    UNION
    SELECT DSTINCT Id2 FROM Friendship
    UNION
    SELECT DSTINCT SenderId FROM Request
    UNION
    SELECT DSTINCT ReceiverId FROM Request
)A