61. Найти пользователей, которые летали только эконом-классом
Условие задачи:
Дана таблица tickets с информацией о билетах пользователей.
Необходимо вывести уникальные user_id пользователей, у которых все билеты имеют класс ECONOMY.
Если у пользователя есть хотя бы один билет другого класса, например BUSINESS, такой пользователь не должен попасть в результат.
Данные:
ticket_id | user_id | ticket_type | price
----------+---------+-------------+------
110 | 500 | ECONOMY | 10000
220 | 600 | BUSINESS | 35000
330 | 600 | ECONOMY | 15000
440 | 750 | ECONOMY | 12000
550 | 800 | BUSINESS | 40000
660 | 750 | ECONOMY | 5000
Спойлеры к решению
Подсказки
user_id.💡 Посчитай общее количество билетов пользователя.
💡 Отдельно посчитай количество билетов класса
ECONOMY.💡 Пользователь подходит, только если эти два количества равны.
Решение
Основной вариант через GROUP BY и HAVING:
SELECT
user_id
FROM tickets
GROUP BY user_id
HAVING COUNT(*) =
COUNT(CASE
WHEN ticket_type = 'ECONOMY' THEN 1
END);
Для каждого пользователя:
COUNT(*)
считает все его билеты, а:
COUNT(CASE
WHEN ticket_type = 'ECONOMY' THEN 1
END)
считает только билеты класса ECONOMY.
Если значения равны, значит у пользователя нет билетов другого класса.
Альтернативный вариант через NOT EXISTS:
SELECT DISTINCT
t.user_id
FROM tickets t
WHERE NOT EXISTS (
SELECT 1
FROM tickets other
WHERE other.user_id = t.user_id
AND (
other.ticket_type <> 'ECONOMY'
OR other.ticket_type IS NULL
)
);
Здесь из результата исключается пользователь, если у него существует хотя бы один билет, который не является ECONOMY.
Для приведённых данных результат:
user_id
-------
500
750
Пользователь 600 не подходит, поскольку у него есть билет BUSINESS, а пользователь 800 вообще не имеет билетов ECONOMY.