数据库中有两个表users
,relationships
。
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
users.is_active=1
relationships
表没有关系的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
请注意,users
和relationships
中有很多行。
如果我在子查询中使用NOT IN,则会出现性能问题。
所以我认为我必须加入外键,但我不知道如何准确地进行查询。
任何建议,谢谢。
谢谢。
答案 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)(列应按此顺序排列)