Выбор пользователей из одной группы с именем - PullRequest
0 голосов
/ 25 января 2020
Users
id  username
1   ryan
2   mike
3   annie
4   lisa 

Groups
id  name
1   football
2   hockey

Permissions 
user_id group_id           
1          1
1          2
2          1
4          2

Итак, я ищу каждого пользователя, который принадлежит хотя бы к одной группе с именем пользователя Райан. Я также хотел бы знать всех, кто не входит в ту же группу.

SELECT Users.username
FROM Users
LEFT JOIN Permissions ON Users.id = Permissions.user_id
LEFT JOIN Groups.id = Permissions.group_id
WHERE Users.id; 

Так вот как я начал, но не знаю, как продолжить.

Ответы [ 2 ]

0 голосов
/ 25 января 2020

Вы можете сделать это с несколькими объединениями пользователей и прав:

select uu.username
from Users u
inner join Permissions p on p.user_id = u.id
inner join Permissions pp on pp.group_id = p.group_id
inner join Users uu on pp.user_id = uu.id and pp.user_id <> u.id
where u.username = 'ryan'

См. demo . Результаты:

| username |
| -------- |
| mike     |
| lisa     |
0 голосов
/ 25 января 2020

Вот один из методов:

with ug as (
      SELECT u.username, g.name
      FROM Users u JOIN
           Permissions p
           ON u.id = p.user_id 
     )
SELECT DISTINCT ug.username
FROM ug
WHERE EXISTS (SELECT 1
              FROM ug ug2
              WHERE ug2.group_id = ug.group_id AND
                    ug2.username = 'Ryan'
             );

Вышеуказанное имя группы присваивается каждому пользователю, а затем обрабатывается как одна таблица. EXISTS используется, чтобы определить, перекрываются ли группы.

Обратите внимание, что groups не требуется, поскольку вы не запрашиваете название группы. Идентификатора достаточно, чтобы ответить на вопрос.

Я не большой поклонник использования select distinct. Обычно это означает, что ядро ​​базы данных выполняет больше работы, чем необходимо - создает дубликаты , а затем их удаляет.

Вот альтернативное решение, использующее exists:

select u.*
from users u
where exists (select 1
              from permissions p join
                   permissions pr
                   on pr.group_id = p.group_id join
                   users ur
                   on pr.user_id = ur.user_id and
                      ur.username = 'Ryan'
              where p.user_id = u.id
             );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...