На главную страницу
Характерные ошибки при решении упражнений. Задача 49
Моисеенко С.И.
Среди пассажиров, которые пользовались услугами не менее двух авиакомпаний, найти
тех, кто совершил одинаковое количество полётов самолетами каждой из этих авиакомпаний.
Вывести имена таких пассажиров.
Эта задача порождает массу ошибочных решений, которые я разделяю на две группы.
К первой группе относятся решения, связанные с неверным прочтением формулировки.
Например, пытаются найти двух пассажиров, которые летали бы одинаково двумя или
большим числом компаний.
Поясню, что рассматривать следует отдельного пассажира и подсчитываеть число полетов,
которое он сделал каждой из авиакомпаний, которыми летал.
Что дальше? Рассмотрим теперь пример из второй группы ошибочных решений:
SELECT DISTINCT name
FROM (SELECT id_psg, id_comp, count(pt.trip_no) as CNT
FROM pass_in_trip pt JOIN trip t ON pt.trip_no=t.trip_no
GROUP BY id_comp,id_psg)a,
(SELECT id_psg, id_comp, count(pt.trip_no) as CNT
FROM pass_in_trip pt JOIN trip t ON pt.trip_no=t.trip_no
GROUP BY id_comp,id_psg)b,
passenger p
WHERE a.id_psg=b.id_psg and a.id_comp<>b.id_comp and a.cnt=b.cnt
and p.id_psg=b.id_psg
Сразу отметим ошибочное DISTINCT name, которое устраняет возможных однофамильцев.
Однако не это здесь главное. В предложении FROM соединяются два одинаковых запроса
SELECT id_psg, id_comp, count(pt.trip_no) as CNT
FROM pass_in_trip pt JOIN trip t ON pt.trip_no=t.trip_no
GROUP BY id_comp,id_psg
которые, как и сказано выше, подсчитывают для каждого пассажира число полетов, которое
он совершил самолетами каждой из компаний.
Соединяются эти запросы по следующим условиям:
- пассажир один и тот же;
- компании разные;
- число полетов совпадает.
Итак, если пассажир совершил, скажем, компанией Aeroflot 3 полета, и также 3 полета
он совершил самолетами компании Don_avia, то такой пассажир удовлетворяет условиям
соединения и будет выведен в результатах запроса. Если пассажир летал всего двумя
компаниями, то это - правильный результат. А если компании три?
Если в результате рассмотренного выше подзапроса мы получим
Bruce Willis Don_avia 2
Bruce Willis Aeroflot 2
Bruce Willis Dale_avia 1
то пассажир Bruce Willis не отвечает условиям задачи, хотя рассматриваемый запрос
выведет его, поскольку в запросе будут соединены первые две строки.
Итак, число полетов пассажира каждой из компаний, которыми он летал должно находиться
в пропорции 1:1:...:1
Перейти к решению
задачи #49
На главную страницу