MySQL在没有NOT IN的情况下联接两个表

时间:2019-07-03 02:16:30

标签: mysql

数据库中有两个表usersrelationships

CREATE TABLE users(
id int primary key auto_increment,
nickname varchar(20),
is_active TINYINT
)

CREATE TABLE relationships(
id int primary key auto_increment,
user_id int,
target_user_id int,
FOREIGN KEY(user_id) REFERENCES users(id),
FOREIGN KEY(target_user_id) REFERENCES users(id)
)
mysql> select * from users;
+----+----------+-----------+
| id | nickname | is_active |
+----+----------+-----------+
|  1 | hide     |         1 |
|  2 | john     |         1 |
|  3 | ben      |         0 |
|  4 | test     |         1 |
|  5 | gogo     |         1 |
+----+----------+-----------+

mysql> select * from relationships;
+----+---------+----------------+
| id | user_id | target_user_id |
+----+---------+----------------+
|  1 |       1 |              2 |
|  2 |       1 |              4 |
+----+---------+----------------+

我必须在特定条件下提取users.id

如果有users.id = 1

,我会解释
  1. users.is_active=1
  2. 通过relationships表没有关系的
  3. 用户。您知道在当前relationships表中,user_id = 1有2行,target_user_id = 2 and 4。因此查询结果不包含user_id = 2 and 4

使用NOT IN,非常简单。

SELECT id FROM users WHERE is_active=1 AND id NOT IN(SELECT target_user_id FROM relationships WHERE user_id=1)

RESULT : 1, 5

请注意,usersrelationships中有很多行。

如果我在子查询中使用NOT IN,则会出现性能问题。

所以我认为我必须加入外键,但我不知道如何准确地进行查询。

任何建议,谢谢。

谢谢。

2 个答案:

答案 0 :(得分:1)

尝试一下:我敢肯定,foo Myfoo[3] = { {1, 100}, {2, 300}, {5, 100} }; LEFT JOIN的方法肯定会为您服务

IS NULL

答案 1 :(得分:0)

查询没有问题。 MySQL应该能够使用您的索引。

但是,您也可以使用左联接:

SELECT
    users.id
FROM
    users
    LEFT JOIN relationships ON (
            users.id = relationships.target_user_id
/*
        -- un-comment if filtering by user is needed
        AND relationships.user_id = 1
*/
    )
WHERE
        users.is_active=1
    AND relationships.target_user_id IS NULL
    -- addition filtering can be here

更新: 如果您按用户进行过滤,则可以尝试向relationships表中添加组合索引(user_id,target_user_id)(列应按此顺序排列)