GROUP_CONCAT() 类似于不匹配的 return 字段的函数?

GROUP_CONCAT() like function to return fields that don't match?

我的数据库中有三个表,为了便于讨论,假设它们是:

USERS   
-----
user_id
user_name

ROLES
-----
role_id
role

USER_ROLES
----------
user_role_id
user_id
role_id

我可以轻松地使用 GROUP_CONCAT() 到 return 用户 拥有的逗号分隔角色列表,如下所示:

SELECT u.user_id, u.user_name, GROUP_CONCAT(role) AS roles_held
FROM users u,
     roles r,
     user_roles ur
WHERE u.user_id = ur.user_id
  AND r.role_id = ur.role_id
GROUP BY u.user_id, u.user_name;

我想做的也是return用户没有的角色列表。

我最初的想法是使用子查询然后将其连接起来,但我似乎无法让它发挥作用。有人能指出我正确的方向吗?

谢谢!

编辑: 澄清一下,所需的输出将是一个查询 returns user_id,user_name,一个连接的字符串用户确实拥有的角色和用户不拥有的角色的串联字符串。例如:

USER_ID    USER_NAME    ROLES_HELD      ROLES_LACKED
1          Bob          User,Writer     Editor,Admin
2          Doug         User            Writer,Editor,Admin

我同意在这里使用 CROSS JOIN,但它不需要那么复杂:

SELECT
    u.user_id,
    u.user_name,
    GROUP_CONCAT(case when ur.user_id is not null then r.role end) AS roles_held,
    GROUP_CONCAT(case when ur.user_id is null then r.role end) as roles_lacked
FROM
    users u
    CROSS JOIN roles r
    LEFT JOIN user_roles ur ON
        u.user_id = ur.user_id
        AND r.role_id = ur.role_id
GROUP BY
    u.user_id, u.user_name

您可以尝试加入table角色两次,第一次是获得保留角色,第二次是缺少角色。

SELECT u.user_id, 
       user_name, 
       GROUP_CONCAT(DISTINCT r.role)  AS role_held, 
       GROUP_CONCAT(DISTINCT r1.role) AS role_lacked 
FROM   users u 
       INNER JOIN user_roles ur 
               ON u.user_id = ur.user_id 
       INNER JOIN roles r 
               ON r.role_id = ur.role_id 
       INNER JOIN roles r1 
               ON NOT EXISTS (SELECT 1 
                              FROM   user_roles ur1 
                              WHERE  user_id = u.user_id 
                                     AND role_id = r1.role_id) 
GROUP  BY u.user_id, 
          user_name 

我创建了一个演示 here