我有2个具有多对多关系的实体。用户 - Roles_Users - 角色
如何编写一个查询,向我返回只有一个角色的所有用户,即角色名称" customer"。我写了这样的话:
SELECT `users`.* FROM `users`
INNER JOIN `roles_users` ON `roles_users`.`user_id` = `users`.`id`
INNER JOIN `roles` ON `roles`.`id` = `roles_users`.`role_id`
WHERE roles.name not in ('admin' , 'sac', 'superadmin', 'customer_service' , 'supplier');
但它仍然带给我的用户不仅仅是角色'客户'。
我需要的用户只有'客户'没有别的
答案 0 :(得分:1)
这就是我要解决的问题:
SELECT `users`.*
FROM `users`
WHERE id IN
(
SELECT `roles_users`.`user_id`
FROM `roles_users`
INNER JOIN `roles`
ON `roles`.`id` = `roles_users`.`role_id`
GROUP BY `roles_users`.`user_id`
HAVING COUNT(*) = 1 -- only a single role
AND MAX(roles.name) = 'customer' -- and this role is 'customer'
)
顺便说一句,没有必要使用所有这些反对:
SELECT *
FROM users
WHERE id IN
(
SELECT roles_users.user_id
FROM roles_users
JOIN roles
ON roles.id = roles_users.role_id
GROUP BY roles_users.user_id
HAVING COUNT(*) = 1 -- only a single role
AND MAX(roles.name) = 'customer' -- and this role is 'customer'
)
这不容易阅读(和写)吗?
答案 1 :(得分:0)
直接比较角色名称,因为使用in可以获得其他非必需值
SELECT `users`.* FROM `users` INNER JOIN `roles_users` ON `roles_users`.`user_id` = `users`.`id` INNER JOIN `roles` ON `roles`.`id` = `roles_users`.`role_id` WHERE roles.name ='customer'
答案 2 :(得分:0)
为什么不直视具有特定角色的用户?
SELECT `users`.* FROM `users`
JOIN `roles_users` ON `roles_users`.`user_id` = `users`.`id`
JOIN `roles` ON `roles`.`id` = `roles_users`.`role_id`
WHERE `roles`.name = 'customer';
答案 3 :(得分:0)
在WHERE子句中使用NOT EXISTS
子查询:
SELECT u.*
FROM users u
INNER JOIN roles_users ru ON ru.user_id = u.id
INNER JOIN roles r ON r.id = ru.role_id
WHERE r.name = 'customer'
AND NOT EXISTS (
SELECT *
FROM roles_users ru1
WHERE ru1.user_id = ru.user_id
AND ru1.role_id <> ru.role_id
)
NOT EXISTS
条件将确保不会为用户分配任何其他角色。
更短但更慢的解决方案可能是:
SELECT u.*
FROM users u
INNER JOIN roles_users ru ON ru.user_id = u.id
INNER JOIN roles r ON r.id = ru.role_id
GROUP BY u.id
HAVING GROUP_CONCAT(r.name) = 'customer'