Как мне выбрать всех спортсменов, которые никогда не занимались бегом и плаванием?

#sql

Вопрос:

Как мне выбрать всех спортсменов, которые никогда не занимались бегом и плаванием?

activity_log

пользователь неделя нет. Активность
a 2 плавание
a 2 поднимание
b 2 поднимание
a 2 поднимание
d 2 поднимание
c 2 Выполняется
b 3 скалолазание
c 3 Выполняется
a 3 поднимание
 SELECT a.user 
FROM activity_log a
WHERE a.activity = 'lifting' AND a.user NOT IN (
 SELECT DISTINCT b.user 
 FROM activity_log b 
 WHERE b.activity IN ('running', 'swimming'))
 

пока что вот мое мнение, но есть ли лучший способ для этого?

Ответ №1:

Сделай а GROUP BY . Используйте это HAVING положение, чтобы избегать бегунов и пловцов.

 SELECT a.user 
FROM activity_log a
GROUP BY a.user
HAVING SUM(when A.activity IN ('running', 'swimming') then 1 else 0 end) = 0
 

В качестве альтернативы, используйте EXCEPT :

 SELECT a.user FROM activity_log a
EXCEPT
SELECT a.user FROM activity_log a WHERE A.activity IN ('running', 'swimming')
 

(ГРУППИРОВКА ПО запросу, вероятно, будет работать лучше.)

Ответ №2:

Конечно, есть немного более быстрый способ сделать это.

Вы можете использовать JOIN вместо WHERE как JOINS есть faster чем WHERE . Вот как может выглядеть ваш запрос:

 SELECT a.user 
FROM activity_log a
LEFT JOIN 
(
 SELECT DISTINCT b.user 
 FROM activity_log b 
 WHERE b.activity IN ('running', 'swimming')
) as c
ON a.user=c.user
WHERE a.activity = 'lifting' AND c.user IS NULL 
 

Как вы, возможно, знаете, при использовании LEFT JOIN мы получаем значение NULL user , если у них нет активности в качестве running или swimming . Следовательно, IS NULL нужно фильтровать.