#mysql #sql
#mysql #sql
Вопрос:
Я пытаюсь написать запрос, который извлекает всех пользователей, которые принадлежат к группе A
, но исключает пользователей, которые принадлежат группам B
, C
amp; D
.
Пользователи однозначно идентифицируются user_id
в users
таблице, но могут иметь несколько записей в groups
таблице.
У меня есть следующий запрос, но он не работает:
SELECT user_id
FROM users
LEFT JOIN groups USING (user_id)
WHERE groups.name = 'A'
AND groups.name NOT IN ('B', 'C', 'D')
Это просто выбирает всех пользователей из группы A
.
Как включить кого-либо из группы A
, но исключить их, если они находятся в группах B
, C
amp; D
?
Комментарии:
1. Как
groups.name
выглядят данные в этом файле? Это список с разделителями, какA,B
?2. Нет, это просто varchar. В этом случае либо
A
,B
,C
либоD
.
Ответ №1:
Используйте агрегацию:
SELECT user_id
FROM groups
GROUP BY user_id
HAVING SUM(g.name = 'A') > 0 AND
SUM(g.name IN ('B', 'C', 'D')) = 0;
Примечание: Вам не нужно присоединяться к users
. Ваш запрос выбирает только идентификатор пользователя, который находится в groups
таблице. Конечно, если вам нужны дополнительные столбцы из users
, вы можете присоединиться к нему (или использовать in
или exists
).
Комментарии:
1. Не могли бы вы также добавить пример для объединения?
2. @Dangerman1988 . . . Это отвечает на вопрос, который вы задали. Должно быть довольно ясно, как добавить
join
в запрос.
Ответ №2:
использование существует
select t1.user_id from users t1
where exists( select 1 from groups t2 where t1.user_id=t2.user_id
and t2.name='A')
and not exists( select 1 from groups t2 where t1.user_id=t2.user_id
and t2.name NOT IN ('B', 'C', 'D') )
Комментарии:
1. Это наоборот, я хочу исключить их, если они принадлежат к любому из B, C или D
Ответ №3:
Вы можете использовать EXISTS
для случая имени группы A
и NOT EXISTS
для случая имен групп B, C, D
:
select distinct user_id
from groups g
where
exists (
select 1 from groups where user_id = g.user_id and name = 'A'
)
and not exists (
select 1 from groups where user_id = g.user_id and name in ('B', 'C', 'D')
)