Я хочу исключить людей, которые присоединились к определенной группе. Например, если некоторые студенты записались в оркестр, а я хочу получить список студентов, которые НЕ записывались в оркестр, как мне это сделать?
Я не могу просто сделать предложение Group By, потому что некоторые студенты могли вступить в несколько клубов и обойти условие Where и по-прежнему отображаться в запросе, как показано здесь.
Я думаю об использовании оператора CASE в предложении SELECT, чтобы пометить человека как «1», если он присоединился к Orchestra, и «0», если нет, но я изо всех сил пытаюсь написать агрегированную функцию CASE, что приведет к проблемы из предложения GROUP BY.
Есть мысли о том, как пометить людей с определенным значением строки?
По-видимому, моя таблица не была сохранена в SQLFiddle, поэтому вы можете вставить приведенный ниже код на свой экран:
CREATE TABLE activity ( PersonId, Club) as
select 1, 'Soccer' from dual union
select 1, 'Orchestra' from dual union
select 2, 'Soccer' from dual union
select 2, 'Chess' from dual union
select 2, 'Bball' from dual union
select 3, 'Orchestra' from dual union
select 3, 'Chess' from dual union
select 3, 'Bball' from dual union
select 4, 'Soccer' from dual union
select 4, 'Bball' from dual union
select 4, 'Chess' from dual;
@nbwoodward Да, ГДЕ не сработает, потому что человек может вступить в несколько клубов. Он удалит строки, в которых есть «Оркестр», но не будет принимать PersonID полностью. Я тестирую комментарий Саги прямо сейчас.
ах, конечно ... Вы также можете выбрать список идентификаторов пользователей, которые нужно исключить (я поставил ответ ниже).
Возможно ли иметь «учеников», которые не присоединились к ЛЮБОМУ клубу, и поэтому они не будут включены в эту таблицу в первую очередь? Разве вам не нужно их возвращать? Если вы это сделаете, то простой агрегированный запрос только по этой таблице не имеет шансов дать правильный результат.


Используйте предложение HAVING вместо WHERE с выражением case:
HAVING max(case when column = ‘string’ then 1 else 0 end) = 0
Добавьте это после вашей группы.
Кажется, работает! Хотя это показывает только людей, у которых есть строка с «строкой» (противоположная тому, что я хотел), я смог использовать «И НЕ» для компенсации. Спасибо!
select * from
(
select a.*, case when Club ='Orchestra' then 1 else 0 end flag
from activity a
) where flag =1; --> get some students signed up for an Orchestra club
select * from
(
select a.*, case when Club ='Orchestra' then 1 else 0 end flag
from activity a
) where flag =0; --> get students not signed up for an Orchestra club
Как насчет выбора списка идентификаторов пользователей из таблицы действий и его исключения:
SELECT * FROM users WHERE id NOT IN
(SELECT PersonId FROM activity WHERE Club = 'Orchestra');
Вы можете использовать подзапрос, чтобы вернуть список людей, которых нужно исключить.
-- Returns person 2 and 4.
SELECT
PersonId
FROM
activity
WHERE
PersonId NOT IN
(
-- People to exclude.
SELECT
PersonId
FROM
activity
WHERE
Club = 'Orchestra'
)
GROUP BY
PersonId
;
РЕДАКТИРОВАТЬ Убрал лишнее внятное в подзапросе - спасибо @mathguy.
DISTINCT в подзапросе определенно неверен. DISTINCT - дорогостоящая операция, и она никоим образом не помогает операции NOT IN.
Ага! Остался по ошибке после тестирования.
Есть ли причина, по которой вы не можете использовать предложение WHERE?