选择NOT IN和多对多关系

时间:2013-02-12 01:46:28

标签: mysql many-to-many

我有很多关系

--------------------
| user_id | name   |
--------------------
| 1       | user1  |
--------------------
| 2       | user2  |
--------------------
| 3       | user3  |
--------------------


--------------------
| type_id | name   |
--------------------
| 1       | type1  |
--------------------
| 2       | type2  |
--------------------
| 3       | type3  |
--------------------

---------------------
| user_id | type_id |
---------------------
| 1       | 1       |
---------------------
| 1       | 2       |
---------------------
| 1       | 3       |
---------------------
| 2       | 1       |
---------------------
| 2       | 2       |
---------------------
| 3       | 3       |
---------------------

我正在尝试构造一个查询,以便如果我的用户是类型3,则根本不返回该用户。到目前为止,我的查询排除了类型为3的用户,但如果还为其分配了其他类型,则会返回这些用户。

SELECT COUNT(DISTINCT `t`.`user_id`) 
FROM `user` `t` 
LEFT OUTER JOIN `type` `type_type` ON (`t`.`user_id`=`type_type`.`user_id`) 
LEFT OUTER JOIN `type` `type` ON (`type`.`type_id`=`type_type`.`type_id`) 
WHERE ((type.type_ids NOT IN (3));

上述查询仍然会返回user_id 1,因为该用户被分配了多种类型,如何分配3类用户,无论他们分配了多少其他类型?

2 个答案:

答案 0 :(得分:6)

请尝试使用where子句:

where t.user_id not in (select user_id from usertypes where type_id = 3)

在MySQL中,以下内容可能更有效:

where not exists (select 1 from usertypes ut where ut.type_id = 3 and ut.user_id = t.user_id)

顺便说一下,“t”是users的糟糕别名,尤其是当您使用另一个名为types的表时。 “你”将是一个更好的别名。

答案 1 :(得分:3)

您的IN()子查询需要返回user_id的{​​{1}}。

type_id = 3

也可以使用SELECT COUNT(DISTINCT `t`.`user_id`) FROM `user` `t` WHERE `user_id NOT IN (SELECT `user_id` FROM `type_type` WHERE `type_id` = 3) 对同一子查询进行操作,在LEFT JOIN表中查找NULL

type_type

http://sqlfiddle.com/#!2/b36b1/7

实际上连接的子查询甚至不是必需的。它适用于普通SELECT COUNT(DISTINCT `t`.`user_id`) FROM `user` `t` LEFT JOIN ( SELECT `user_id` FROM `type_type` WHERE `type_id` = 3 ) user3 ON t.user_id = user3.user_id WHERE user3.type_id IS NULL

LEFT JOIN

http://sqlfiddle.com/#!2/b36b1/10