mySql-查找用户的所有非好友

mySql-查找用户的所有非好友,mysql,social,Mysql,Social,我正在创建一个社交网络,我正在尝试编写一个mySql查询,以查找不是特定用户朋友的所有用户。 有一个表-USERS,它有id\u user、name和email USERS: user_id , name , email.. 1 Dan a@a.com 2 Ron b@b.com 3 James c@c.com 4 Joe d@d.com 5 Max c@c.com 显示关系状态

我正在创建一个社交网络,我正在尝试编写一个mySql查询,以查找不是特定用户朋友的所有用户。 有一个表-USERS,它有id\u user、name和email

USERS:
user_id , name , email..
1         Dan     a@a.com
2         Ron     b@b.com
3         James   c@c.com
4         Joe     d@d.com
5         Max     c@c.com
显示关系状态=2的朋友表表示这两个人是朋友:

FRIENDS:
user_id , friend_id , status
1             2         2
3             1         2
4             3         2 
什么是mySql查询,它提供了用户\u id=1的非好友用户的用户\u id列表?用户4和5


非常感谢,反连接模式应该足够了

看起来b的isa友元可以在友元表中用a表示为a行,a,b,2或b,a,2。这对我来说并不完全清楚,但我现在假设这是真的

这个查询只是第一次。为了在friends表中双向检查friends,我将在join谓词中使用OR条件

这实质上是从用户处获取所有行,以及从朋友处获取匹配行。诀窍是WHERE子句中的谓词,它消除了在friends中找到匹配项的所有行,只留下那些没有匹配项的用户的行

SELECT u.user_id
     , u.name
  FROM users u
  LEFT
  JOIN friends f
    ON ( f.user_id   = u.user_id AND f.friend_id = ? AND f.status = 2 )
    OR ( f.friend_id = u.user_id AND f.user_id   = ? AND f.status = 2 )
 WHERE f.user_id   IS NULL
    OR f.friend_id IS NULL
不幸的是,MySQL优化器通常不会很好地处理这些问题或条件。作为重新写入时的另一个剪切,我们可以尝试将对朋友的连接拆分为两个左连接

我认为这相当于:

SELECT u.user_id
     , u.name
  FROM users u
  LEFT
  JOIN friends f
    ON ( f.user_id   = u.user_id AND f.friend_id = ? AND f.status = 2 )
  LEFT
  JOIN friends g
    OR ( g.friend_id = u.user_id AND g.user_id   = ? AND g.status = 2 )
 WHERE f.user_id   IS NULL 
   AND g.friend_id IS NULL
我还没有测试第二个查询。。。目标是做同样的事情。来自用户的所有行,以及来自朋友的匹配行,然后筛选出所有匹配的行

编辑

我认为我们还需要从特定用户的用户中筛选出该行。上述查询将返回用户本人,而不是其朋友。为了实现这一点,我们可以添加WHERE子句

使用不存在子查询


@草莓:我不得不在某个地方停下来。从个人满意度的角度来看,我更喜欢在friends表中有两倍多的行,a,b和b,a都在该表中。我可以使用一个内联视图、两个查询和一个UNION ALL set运算符来返回该集合。对于特定用户,我会使用适当的谓词。但是,我们可以通过有条件地交换a和b得到一个等价的结果,而不需要所有的并集。我不得不在某个地方停下来。
 AND u.user_id <> ?
SELECT u.user_id
     , u.name
  FROM users u
 WHERE u.user_id NOT IN ( SELECT f.user_id
                            FROM friends f
                           WHERE f.user_id IS NOT NULL
                             AND f.status = 2
                             AND f.friend_id = ?
                        )
   AND u.user_id NOT IN ( SELECT f.friend_id
                            FROM friends f
                           WHERE f.friend_id IS NOT NULL
                             AND f.status = 2
                             AND f.user_id = ?
                        )
   AND u.user_id <> ?
SELECT u.user_id
     , u.name
  FROM users u
 WHERE NOT EXISTS ( SELECT 1 
                      FROM friends f
                     WHERE f.user_id = u.user_id
                       AND f.status = 2
                       AND f.friend_id = ?
                  )
   AND NOT EXISTS ( SELECT 1
                      FROM friends g
                     WHERE g.friend_id = u.user_id
                       AND g.status = 2
                       AND g.user_id = ?
                  )
   AND u.user_id <> ?