Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Практические SQL запросы на выборку.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
9.64 Mб
Скачать

Включение дубликатов

Агрегатные функции могут также (в большинстве реализаций) использовать аргумент ALL, который помещается перед именем поля, подобно DISTINCT, но означает противоположное: - включать дубликаты.

SELECT Count (snum)

FROM (SELECT all snum

FROM Orders);

ALL считает так же и Null значения.

Агрегаты построенные на скалярном выражении

До этого, вы использовали агрегатные функции с одиночными полями как аргументами. Вы можете также использовать агрегатные функции с аргументами которые состоят из скалярных выражений включающих одно или более полей. (Если вы это делаете, DISTINCT не разрешается.) Предположим, что таблица Продажи имеет еще один столбец который хранит предыдущий неуплаченный баланс (поле blnc) для каждого заказчика. Вы должны найти этот текущий баланс, добавлением суммы приобретений к предыдущему балансу. Вы можете найти наибольший неуплаченный баланс следующим образом:

SELECT MAX (blnc + (amt))

FROM Orders;

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

Предложение group by

Предложение GROUP BY позволяет вам определять подмножество значений в особом поле в терминах другого поля, и применять функцию агрегата к подмножеству. Это дает вам возможность объединять поля и агрегатные функции в едином предложении SELECT.

Например, предположим что вы хотите найти наибольшую сумму приобретений полученную каждым продавцом. Вы можете сделать раздельный запрос для каждого из них, выбрав MAX (amt) из таблицы Продажи для каждого значения поля snum. GROUP BY, однако, позволит Вам поместить их все в одну команду:

SELECT snum, MAX (amt)

FROM Orders

GROUP BY snum;

Вывод для этого запроса показывается в Рисунке 6.

Рисунок 6 Нахождение максимальной суммы продажи у каждого продавца

Вы можете также использовать GROUP BY с многочисленными полями. Совершенствуя вышеупомянутый пример. Предположим, что вы хотите увидеть наибольшую сумму приобретений получаемую каждым продавцом каждый день. Чтобы сделать это, вы должны сгруппировать таблицу Продажи по датам продавцов, и применить функцию MAX к каждой такой группе, подобно этому:

SELECT snum, odate, MAX (amt)

FROM Orders

GROUP BY snum, odate;

Вывод для этого запроса показывается в Рисунке 7.

Рисунок 7 Нахождение наибольшей суммы приобретений на каждый день

Конечно же, пустые группы, в дни когда текущий продавец не имел продаж, не будут показаны в выводе.

Предложение having

Предположим, что в предыдущем примере, вы хотели бы увидеть только максимальную сумму приобретений значение которой выше 3000 руб. Вы не сможете использовать агрегатную функцию в предложении WHERE, потому что предикаты оцениваются в терминах одиночной строки, а агрегатные функции оцениваются в терминах групп строк. Это означает что вы не сможете сделать что-нибудь подобно следующему:

SELECT snum, odate, MAX (amt)

FROM Oreders

WHERE MAX (amt) > 3000

GROUP BY snum, odate;

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

Правильной командой будет следующая:

SELECT snum, odate, MAX (amt)

FROM Orders

GROUP BY snum, odate

HAVING MAX (amt) > 3000;

Вывод для этого запроса показывается в Рисунке 8.

Рисунок 8 Удаление групп агрегатных значений

Аргументы в предложении HAVING следуют тем же самым правилам, что и в предложении SELECT, состоящей из команд использующих GROUP BY. Они должны иметь одно значение на группу вывода. Следующая команда будет запрещена:

SELECT snum, MAX (amt) FROM Orders GROUP BY snum HAVING odate =# 10/03/1988#;

Поле оdate не может быть вызвано предложением HAVING, потому что оно может иметь (и действительно имеет) больше чем одно значение на группу вывода. Чтобы избегать такой ситуации, предложение HAVING должно ссылаться только на агрегаты и поля выбранные GROUP BY. Имеется правильный способ сделать вышеупомянутый запрос (вывод показывается в Рисунке 9):

SELECT snum, MAX (amt)

FROM Orders

WHERE odate = #10/03/1990#

GROUP BY snum;

Рисунок 9 Максимальное значение суммы приобретений у каждого продавца на 3 Октября

Поскольку поля odate нет, не может быть и выбранных полей, значение этих данных меньше чем в некоторых других примерах. Вывод должен вероятно включать что-нибудь такое что говорит - " это - самые большие Продаж на 3 Октября."

Как и говорилось ранее, HAVING может использовать только аргументы которые имеют одно значение на группу вывода. Практически, ссылки на агрегатные функции - наиболее общие, но и поля выбранные с помощью GROUP BY также допустимы. Например, мы хотим увидеть наибольшие продажи для Serres и Rifkin:

SELECT snum, MAX (amt)

FROM Orders

GROUP BY snum

HAVING snum IN (1002, 1007);

Вывод для этого запроса показывается в Рисунке 10.

Рисунок 10 Использование HAVING с GROUP BY полями