MYSQL:显示所有用户角色清单的查询

时间:2016-07-27 03:42:48

标签: mysql

我有一个属于某个角色的用户列表。

我有三个MySQL表:用户角色 userRoles ,它们与两个表相关。

对于“编辑用户”表单,我需要在 roles 表中显示所有可用角色的列表,并在所有这些表中显示用户所属的角色。

我的查询出现问题,因为如果我尝试按角色名称输出列表分组(以避免重复),则所有用户都不会出现在列表中。如果我避免分组,角色列表会有重复。 我尝试过使用DISTINCT,输出仍然是重复的。

以下是我的疑问:

SELECT  roles.roleID, roles.nombreRol AS rolusuario,
                                    usuarios.userID AS usuarioid, 
                                    rolesUsuarios.userID, rolesUsuarios.nombreRol
                            FROM roles LEFT JOIN rolesUsuarios
                            ON roles.nombreRol = rolesUsuarios.nombreRol
                            LEFT JOIN usuarios
                            ON rolesUsuarios.userID = usuarios.userID


SELECT  roles.roleID, roles.nombreRol AS rolusuario,
                                    usuarios.userID AS usuarioid, 
                                    rolesUsuarios.userID, rolesUsuarios.nombreRol
                            FROM roles LEFT JOIN rolesUsuarios
                            ON roles.nombreRol = rolesUsuarios.nombreRol
                            LEFT JOIN usuarios
                            ON rolesUsuarios.userID = usuarios.userID
                            GROUP BY roles.nombreRol

我也试过改变JOINS的顺序作为测试:

                            SELECT roles.roleID, roles.nombreRol,
                                    usuarios.userID, 
                                    rolesUsuarios.userID, rolesUsuarios.nombreRol
                            FROM usuarios LEFT JOIN rolesUsuarios
                            ON usuarios.userID = rolesUsuarios.userID
                            LEFT JOIN roles
                            ON roles.nombreRol = rolesUsuarios.nombreRol
GROUP BY roles.nombreRol

但是这样,我只得到了其中有用户的角色列表。

这是我的三张桌子:

CREATE TABLE roles(
    roleID int unsigned not null auto_increment primary key,
    nombreRol char(50) not null
);

CREATE TABLE usuarios(
    userID int unsigned not null auto_increment primary key,
    userEmail char(50) null,
...
);

CREATE TABLE rolesUsuarios (
    rolesUsuariosID int unsigned not null auto_increment primary key,
    userID int not null,
    nombreRol char(50) not null
);

2 个答案:

答案 0 :(得分:1)

您应该只能从角色中选择,左连接到userRoles,在userRoles.userID上过滤,不接收任何重复项,或者需要使用distinct或grouping来尝试消除它们。

如果userRoles的任何结果都有值,则选择该角色并进行检查,如果该值为null,则取消选中该角色。

类似的东西:

select r.roleID, case when ru.userID is null then 'Unchecked' else 'Checked' end as checkbox
from roles r
left join rolesUsuarios ru
on r.nombreRol = ru.nombreRol
and ru.userID = ?

替换?使用您要过滤的当前用户ID的bind参数。

如果你的nombreRol列的数据是合理的,那么它应该按原样运行,而不需要任何其他聚合。

要显示其他查询的结果(例如,所有用户,针对特定角色),我会使用单独的SQL而不是让一个查询执行这两个操作(如果这是您的目标)。

答案 1 :(得分:1)

表修改建议:

  1. 表rolesUuarios应将roleId作为另一列,并将其设置为roles列中roldeId的外键。
  2. rolesUsuarios中的UserId列应为外键,并指向usuarios表中的UserId。
  3. 在rolesUsuarios表中不需要rolesUsuariosID列。您可以将userId和RoleId组合在一起构成主键。
  4. nombreRol已存在于Roles表中,因此在rolesUsuarios表中不需要。
  5. 您的查询应该是:

    SELECT
        roles.roleID
        ,roles.nombreRol AS rolusuario
        ,rolesUsuarios.userID
    FROM roles 
    LEFT JOIN rolesUsuarios
    ON roles.nombreRol = rolesUsuarios.nombreRol
    

    假设:rolesUsuarios.nombreRol与Roles表中roles.nombreRol列中的值具有相同的值。 如果修改表结构,则上述查询将相应地更改,以保持列的连接。