【发布时间】:2013-09-09 22:04:24
【问题描述】:
我想获取所有只有两个角色的用户,即 1 和 4。
一个用户角色的存储方式如下:
user_id role_id
54321 1
54321 4
54322 1
54323 1
我如何进行查询,获取 user_id 54321,因为它只有两个角色,这两个是 1 和 4?
我可以使用 WHERE role_id IN (1, 4) 但这也会抓取具有其他角色的用户。
【问题讨论】:
标签: mysql
我想获取所有只有两个角色的用户,即 1 和 4。
一个用户角色的存储方式如下:
user_id role_id
54321 1
54321 4
54322 1
54323 1
我如何进行查询,获取 user_id 54321,因为它只有两个角色,这两个是 1 和 4?
我可以使用 WHERE role_id IN (1, 4) 但这也会抓取具有其他角色的用户。
【问题讨论】:
标签: mysql
WHERE role_id IN (1, 4) GROUP BY user_ID HAVING COUNT(DISTINCT role_id) = 2
http://gregorulm.com/relational-division-in-sql-the-easy-way/
【讨论】:
这是集合中集合查询的示例。我喜欢用group by 和having 来解决这些问题,因为这是最通用的方法:
select user_id
from user_roles ur
group by user_id
having sum(role_id = 1) > 0 and
sum(role_id = 4) > 0 and
sum(role_id not in (1, 4)) = 0;
having 子句具有三个条件。第一个计算该角色为 1 的次数,如果至少有一个这样的角色,则 user_id 通过。第二个对 4 执行相同的操作。最后一个检查是否没有其他值。
我喜欢这种结构,因为它很灵活。如果条件是 1 和 4 并且允许其他条件,则只需删除第三个子句。如果条件是 1 或 4 而没有其他条件,那么它看起来像:
having (sum(role_id = 1) > 0 or
sum(role_id = 4) > 0
) and
sum(role_id not in (1, 4)) = 0;
【讨论】:
SELECT u3.user_id
FROM t u1, t u2, t u3
WHERE u1.role_id = 1 AND u2.role_id = 4
AND u3.user_id = u1.user_id
AND u2.user_id = u1.user_id
GROUP BY u3.user_id HAVING COUNT(u3.role_id) = 2;
【讨论】: