选择仅具有一个角色和一个角色的所有用户 - 许多2个多关系

时间:2011-09-14 14:19:08

标签: mysql sql select many-to-many

我的管理区域中有一个页面,我想要禁止用户,但我只想禁止具有一个角色的用户,即用户。这是一些示例数据

用户1 - 角色(被禁止)
用户2 - 角色(管理员,用户)
用户3 - 角色(已关闭)

用户4 - 角色(用户)

只应返回用户4,因为他们是唯一拥有用户角色且用户角色的用户。我尝试在下面编写自己的查询,但却不知道如何排除不仅仅是用户角色的用户。

SELECT users.*, COUNT(*) AS role_count
FROM users
JOIN roles_users
 ON users.id = roles_users.user_id
JOIN roles
 ON roles_users.role_id = roles.id
GROUP BY users.id

WHERE roles.name = 'user'放入其中会role_count = 1

任何帮助表示感谢。

3 个答案:

答案 0 :(得分:2)

SELECT users.*, COUNT(*) AS role_count, 
       SUM(case roles.name when 'user' then 1 else 0 end) AS IsUser
FROM users
JOIN roles_users
 ON users.id = roles_users.user_id
JOIN roles
 ON roles_users.role_id = roles.id
GROUP BY users.id
HAVING COUNT(*) = 1
AND SUM(case roles.name when 'user' then 1 else 0 end) = 1

答案 1 :(得分:0)

SELECT * 
  FROM users
 WHERE EXISTS (
               SELECT * 
                 FROM roles_users
                      JOIN roles 
                         ON roles_users.role_id = roles.id               
                WHERE users.id = roles_users.user_id
                      AND roles.name = 'user'
              )
       AND NOT EXISTS (
                       SELECT * 
                         FROM roles_users
                              JOIN roles 
                                 ON roles_users.role_id = roles.id               
                        WHERE users.id = roles_users.user_id
                              AND roles.name <> 'user'
                      );

答案 2 :(得分:0)

不应该将名称放在内部查询的where子句中,否则只计算名称为“user”的角色。首先选择只有一个角色的用户,然后在这些用户中验证他们的角色是用户角色。

我相信以下内容会这样做。

SELECT 
    u.id
    , roles.name
FROM
    users u
    INNER JOIN roles_users ON u.id = roles_users.user_id
    INNER JOIN roles       ON roles_users.role_id = roles.id
WHERE
    exists (
        SELECT
            users.id, COUNT(*) AS role_count
        FROM
            users u2
            JOIN roles_users ON u2.id = roles_users.user_id
        WHERE
            u2.id = u.id
        GROUP BY 
            users.id
        HAVING COUNT(*) = 1
           )
    AND roles.name = 'user'