SQL:如何在一个 table 中查找没有引用另一个 table 中的行的行?

SQL: How to find rows in one table that have no references to rows in another tables?

我有三个 table:usersroomsroom_users。 用户可以有很多房间,房间也可以有很多用户,所以这是多对多的关系。

users table:

+----+-----------+-----+
| id |   name    | age |
+----+-----------+-----+
| 1  | Christian | 19  |
| 2  | Ben       | 36  |
| 3  | Robert    | 52  |
| 4  | Monica    | 25  |
| 5  | Alice     | 26  |
| 6  | William   | 18  |
+----+-----------+-----+

rooms table:

+----+----------+
| id |   name   |
+----+----------+
| 1  | College  |
| 2  | Work     |
| 3  | Football |
+----+----------+

room_users table表示用户和房间的关系:

+---------+---------+
| user_id | room_id |
+---------+---------+
| 1       | 1       |
| 1       | 3       |
| 2       | 2       |
| 4       | 1       |
| 5       | 2       |
| 6       | 1       |
| 6       | 3       |
+---------+---------+

所以,有了这些 tables 我们可以说:

现在,如果我想查找确实属于足球室的用户 (id),我应该使用此查询:

SELECT user_id FROM room_users WHERE room_id = 3

此查询的输出:

+---------+
| user_id |
+---------+
| 1       |
| 6       |
+---------+

这是正确的,只有 Christian(1) 和 William(3) 属于足球室。

但是如何找到不属于足球房的用户呢? 在这种情况下,查询必须 return 2、3、4 和 5 个 ID。即除第一个查询的ID外的所有ID。

是否可以使用 LEFT JOIN 来实现? 据我所知,它比使用子查询更有效。

提前致谢!

编辑:

我找到了可以解决问题的查询,但是这个查询在大型数据库上非常慢:

SELECT users.id FROM users WHERE 0=(SELECT COUNT(*) FROM room_users WHERE user_id=users.id AND room_id=3);

没有相关行为,尝试这样的事情:

SELECT u.*
  FROM users AS u
  LEFT JOIN (
          SELECT DISTINCT user_id FROM room_users WHERE room_id = 3
       ) AS v
    ON v.user_id = u.id
 WHERE v.user_id IS NULL
;

对于性能问题,请先查看 explain/execution 计划和索引的使用。

您可以找到那些属于足球室的用户,然后排除那些使用不在的用户。 您也可以使用 JOIN

SELECT u.*
FROM
users u
WHERE user_id NOT IN
(SELECT user_id FROM room_users WHERE room_id=3)

你说得对,这可以用左连接来完成。

SELECT
    u.id
FROM
    users u
LEFT JOIN room_users ur
ON u.id = ur.user_id
AND ur.room_id = 3
WHERE
    ur.room_id is null;