SQL - вложенные объединения - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть база данных 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;

Это только кажетсявыводить роли для 1-го user_id в таблице Roles.И он выводит более 1 одной и той же записи.Например, мой вывод выглядит так:

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 голосов
/ 08 февраля 2019

Посмотрите на этот фрагмент вашего запроса: 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
0 голосов
/ 07 февраля 2019

использовать 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
0 голосов
/ 07 февраля 2019

Попробуйте использовать запрос ниже.

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;
0 голосов
/ 07 февраля 2019

Вы можете использовать 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...