SQL-嵌套联接

时间:2019-02-07 06:34:31

标签: mysql sql join database-design

我有一个mySQL数据库,正在其中尝试输出用户及其分配的管理角色的列表。我的桌子看起来像:

Users:
-------
- id
- fname
- lname


Role_Names
-----------
- rn_id
- role_name


Roles
---------
- role_id
- user_id

这是一些数据:

Users:
-------
1  'Chris'  'Christy'
2  'Brian'  'Bobson'
3  'Jen'    'Sanders'

Role_Names
--------------
1  'admin'
2  'exec'
3  'employee'

Roles
-----------
1   1
1   2
1   3
2   3
3   3
3   2

对于我的查询,我正在使用:

SELECT Users.fname, Role_Names.role_name from Users INNER JOIN 
    Roles on Users.id = Roles.user_id
        INNER JOIN Role_Names
            ON Roles.rn_id = Roles.role_id;

它似乎仅在user_id表中为第一个Roles输出角色。并且它输出多个相同的记录。例如,我的输出如下:

first_name      role_name
--------------------------------------
Chris           exec
Chris           exec
Chris           exec
Chris           employee
Chris           employee
Chris           employee
Chris           admin
Chris           admin
Chris           admin

而我希望有更多类似的东西:

first_name      role_name
--------------------------------------
Chris           employee
Chris           admin
Chris           exec
Brian           employee
Jen             employee
Jen             exec
...

到目前为止,我不确定这是我的表结构有缺陷还是我使用的联接不正确,或者那是我什至不知道的其他内容。有人可以帮我指出正确的方向吗?

4 个答案:

答案 0 :(得分:2)

凝视您的查询内容:ON Roles.rn_id = Roles.role_id;

这不是你的意思!

这是固定查询(格式更清晰):

SELECT  Users.fname, Role_Names.role_name
    FROM        Users AS u
    INNER JOIN  Roles AS r        ON u.id = r.user_id
    INNER JOIN  Role_Names AS rn  ON rn.rn_id = r.role_id

提示:许多:许多映射表(您的Roles)通常由与其相关的两件事来命名。因此,我建议使用User_Roles。然后,第三张表可以简单地为Roles。导致

SELECT  Users.fname, Role_Names.role_name
    FROM        Users AS u
    INNER JOIN  User_Roles AS ur ON u.id = ur.user_id
    INNER JOIN  Roles      AS r  ON r.rn_id = ur.role_id

答案 1 :(得分:1)

您可以像下面这样使用DISTINCT

SELECT DISTINCT Users.fname, Role_Names.role_name from Users INNER JOIN 
    Roles on Users.id = Roles.user_id
        INNER JOIN Role_Names
            ON Roles.rn_id = Roles.role_id;

答案 2 :(得分:1)

使用distinct

with Users as
(
select 1 id, 'Chris' fname,  'Christy' lname
union all
select 2 , 'Brian',  'Bobson' union all
select 3  ,'Jen'  ,  'Sanders'
),Role_Names as
(
select 1 rn_id,  'admin' role_name
union all
select 2 , 'exec' union all
select 3 , 'employee'
) , Roles as
(
select 1 role_id,1 user_id
    union all
     select 1,2 union all
     select 1,3 union all
     select 2  , 3 union all
select 3  , 3 union all
select 3 ,  2
) SELECT distinct Users.fname, Role_Names.role_name 
  from Users left JOIN 
    Roles on Users.id = Roles.user_id
        left JOIN Role_Names
            ON Role_Names.rn_id = Roles.role_id

您错过了加入查询

JOIN Role_Names ON Roles.rn_id = Roles.role_id -- here both side you use Roles

答案 3 :(得分:0)

尝试使用以下查询。

SELECT Users.fname, Role_Names.role_name 
from Roles RIGHT OUTER JOIN 
    Users on Users.id = Roles.user_id
        INNER JOIN Role_Names
            ON Roles_Names.rn_id = Roles.role_id;