Упражнение 124

Среди пассажиров, которые пользовались услугами не менее двух авиакомпаний, найти тех, кто совершил одинаковое количество полётов самолетами каждой из этих авиакомпаний. Вывести имена таких пассажиров.

Эта задача порождает массу ошибочных решений, которые я разделяю на две группы. К первой группе относятся решения, связанные с неверным прочтением формулировки. Например, пытаются найти двух пассажиров, которые летали бы одинаково двумя или большим числом компаний.

Поясню, что рассматривать следует отдельного пассажира и подсчитываеть число полетов, которые он совершил самолетами каждой из авиакомпаний.

Что дальше? Рассмотрим теперь пример из второй группы ошибочных решений:

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;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]

Сразу отметим ошибочное 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;
mssql
🚫
[[ error ]]
[[ column ]]
[[ value ]]
которые, как и сказано выше, подсчитывают для каждого пассажира число полетов, которое он совершил самолетами каждой из компаний.

Соединяются эти запросы по следующим условиям:

  • пассажир тот же самый;
  • компании разные;
  • число полетов совпадает.

Итак, если пассажир совершил, скажем, компанией Aeroflot 3 полета, и также 3 полета он совершил самолетами компании Don_avia, то такой пассажир удовлетворяет условиям соединения и будет выведен в результатах запроса. Если пассажир летал всего двумя компаниями, то это - правильный результат. А если компании три или больше?

Если в результате рассмотренного выше подзапроса мы получим

Bruce WillisDon_avia2
Bruce WillisAeroflot2
Bruce WillisDale_avia1
то пассажир Bruce Willis не отвечает условиям задачи, хотя рассматриваемое решение выведет его, поскольку в запросе будут соединены первые две строки.

Итак, число полетов пассажира каждой из компаний, которыми он летал, должно находиться в пропорции 1:1:…1.

Решить задачу на SQL-EX.RU