Точно такого же результата можно было добиться построив запрос с использованием группировки по колонкам PR_NAME2 , PR_NAME3 , PR_NAME и применив HAVING COUNT(*) >1
Следующий запрос проиллюстрирует другой пример использования функции COUNT в подзапросе (в этом случае использование подзапроса является единственным способом получения результата). Итак получим фамилию, имя, отчество пассажиров, которые приобрели более одного билета в течении 2008 года, также выведем номер авиалинии и дату вылета из билета. Внутренний подзапрос подсчитает количество билетов за 2008 год для каждой личности, которые извлекаются внешним запросом. При этом внешний запрос выбирает только те строки, где количество найденное внутреннем запросом будет больше одного (иными словами у этой личности больше одного билета), а также производит внутреннее объединение таблиц PERSON и TICKET. . Внутренний и внешний запрос связаны при помощи приравнивания кода личности из внешнего запроса и кода личности указанного в билете из внутреннего запроса. Для того чтобы данные на билеты приобретенные одним пассажиром выводились вместе, результат упорядочиваем по фамилии и имени.
Получаем запрос: [46]
SELECT P.PR_NAME2AS"Имя",
P.PR_NAME3AS"Отчество",
P.PR_NAMEAS"Фамилия",
T.TC_FL_NUMAS"Номер авиалинии",
T.TC_FL_DATEAS"Дата вылета"
FROM PERSONP
INNER JOIN TICKETTONT.TC_PR_CODE=P.PR_CODE
WHERE T.TC_FL_DATEBETWEEN'1.01.08'AND'31.12.08'
AND (SELECT COUNT(*) FROM TICKET
WHERE (TC_PR_CODE=P.PR_CODE)
AND (TC_FL_DATEBETWEEN'1.01.08'AND'31.12.08')) >1
ORDER BY P.PR_NAME,P.PR_NAME2
Другой способ получить этот же результат – это воспользоваться вариантом IN. Как правило, связные подзапросы можно заменить на вариант IN, внутри которого находится подзапрос.
Для получения результата внутренний подзапрос должен найти коды всех пассажиров имеющих более одного билета в течении одного года, для этого нужно получить код личности (TC_TR_CODE) из таблицы TICKET сгруппировав результат по этому коду. Для выделения тех кодов, которые встречаются более одного раза, используем HAVING COUNT(*) >1. Внешний запрос выведет фамилии, имена, отчества, номера авиалинии и даты вылета для людей, коды которых были найдены во внутреннем запросе.
Запрос будет иметь вид: [47]
SELECT P.PR_NAME2AS "Имя",
P.PR_NAME3AS "Отчество",
P.PR_NAME AS"Фамилия",
T.TC_FL_NUMAS"Номер авиалинии",
T.TC_FL_DATEAS"Дата вылета"
FROM PERSONP
INNER JOIN TICKETTONT.TC_PR_CODE=P.PR_CODE
WHERE T.TC_FL_DATEBETWEEN'1.01.08'AND'31.12.08'
AND T.TC_PR_CODEIN
(SELECT TC_PR_CODEFROMTICKET
WHERE TC_FL_DATEBETWEEN'1.01.08'AND'31.12.08'
GROUP BY TC_PR_CODEHAVING COUNT(*) >1)
ORDER BY P.PR_NAME,P.PR_NAME2
В результате выполнения запроса получим:
Листинг 24. Список пассажиров, которые приобрели более одного билета в течении 2008 года, также выводится номер авиалинии и дата вылета из билета. (с использованием GROUP BY и HAVING в подзапросе)