129 подписчиков

Разбор задачи SQL №16 (с ошибкой)

840 прочитали
Задача номер 16. Вывести отсортированный по количеству перелетов (по убыванию) и имени (по возрастанию) список пассажиров, совершивших хотя бы 1 полет.

Задача номер 16. Вывести отсортированный по количеству перелетов (по убыванию) и имени (по возрастанию) список пассажиров, совершивших хотя бы 1 полет.

Задача номер 16. Вывести отсортированный по количеству перелетов (по убыванию) и имени (по возрастанию) список пассажиров, совершивших хотя бы 1 полет.-2

Задачка интересна тем, что в ней есть ошибка в онлайн-тренажере. Для начала - как бы я решал эту задачу. Запрос несложный, но... неправильный!

SELECT

p.name,

COUNT(DISTINCT pit.trip) AS count

FROM Pass_in_trip AS pit

JOIN Passenger AS p ON p.id = pit.passenger

GROUP BY p.id

ORDER BY count DESC, p.name ASC

Задача номер 16. Вывести отсортированный по количеству перелетов (по убыванию) и имени (по возрастанию) список пассажиров, совершивших хотя бы 1 полет.-3

В разборе задачи №5 я писал, что COUNT(DISTINCT id) лучше, чем COUNT(*), т.к. помогает в том числе избежать дублей при джоинах. В текущей задаче дублей при джойнах не наблюдается, но все равно пример показательный.

Задача номер 16. Вывести отсортированный по количеству перелетов (по убыванию) и имени (по возрастанию) список пассажиров, совершивших хотя бы 1 полет.-4

Видим, что для пассажира 'Michael Caine' COUNT(DISTINCT trip) дал результат 3, а COUNT(*) = 4. Лезем дальше в таблицы. Пропускаю этап, где я определил, что id этого пассажира Passenger.id = 14 и что мы видим по нему в таблице Pass_in_trip? Видим, что на одном рейсе 7771 он купил 2 места! Поэтому COUNT(DISTINCT trip) = 3, а COUNT(*) = 4.

Задача номер 16. Вывести отсортированный по количеству перелетов (по убыванию) и имени (по возрастанию) список пассажиров, совершивших хотя бы 1 полет.-5

Я абсолютно уверен, что тренажер, подсунув эту задачку с небольшой хитростью, обманул сам себя. Пассажир совершил 3 полета, но чтобы получить выполнение задания, нужно в запросе поставить COUNT(*), который вернет для этого пассажира число 4. Ай-яй-яй, тренажер!

Задача номер 16. Вывести отсортированный по количеству перелетов (по убыванию) и имени (по возрастанию) список пассажиров, совершивших хотя бы 1 полет.-6