#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
нужно фильтровать.