У меня есть таблица, в которой user_id связан с ролью пользователя, поэтому не обязательно 1: 1 от пользователя к роли, потому что у него может быть несколько ролей.

Я хочу выбрать только пользователей с role_id = 2, а не любую другую роль. Вы можете помочь?

select user_id, role_id 
from users u
join roles r on u.user_id=r.user_id

(простое добавление where role_id=2 неверно).

Токовый выход:

user_id  role_id
1        2
1        other
1        3
2        2
3        0

Ожидаемый результат:

user_id  role_id
2        2
0
user8834780 14 Мар 2018 в 00:27

2 ответа

Лучший ответ

Вот один из методов агрегирования:

select user_id, 2
from roles r
group by user_id
having min(role_id) = 2 and min(role_id) = max(role_id);

Если role_id может быть NULL, вы можете настроить это на:

having min(role_id) = 2 and min(role_id) = max(role_id) and count(role_id) = count(*)
1
Gordon Linoff 14 Мар 2018 в 03:04

Попробуйте это, он также хорошо работает с NULL:

SELECT user_id, 2 FROM (
    SELECT user_id, COUNT(role_id)
    FROM roles
    GROUP BY user_id
    HAVING MIN(role_id) = 2 AND MAX(role_id) = 2 AND COUNT(*) = COUNT(role_id)
) AS t;

Он огромен, но я думаю, что это самый простой способ сделать это в PostgreSQL.

0
Daniele Murer 13 Мар 2018 в 22:34