Читать книгу «Основы программирования в СУБД Oracle. SQL+PL/SQL.» онлайн полностью📖 — О. А. Ткачева — MyBook.
image

Группировка

Чаще всего агрегатные функции используются в запросах с группировкой. В общем виде запрос с группировкой может быть представлен в следующем виде:

SELECT {список столбцов*), {агрегатные функции}

FROM {таблица}

WHERE {условия}

GROUP BY {список столбцов*}

HAVING {условия на группу};

Списки столбцов в предложениях SELECT и GROUP BY должны совпадать.

Предложение GROUP BY разбивает данные на группы, и запрос выводит обобщенные данные о каждой группе.

Рассмотрим примеры задач, для решения которых необходимо использовать группировку и агрегатные функции.

Пример 4.7. Для каждого отдела определить суммарную зарплату

SELECT department_id, SUM (salary) AS SUM_salary

FROM Employees

GROUP BY department_id

ORDER BY department_id;


Пример 4.8. Для каждого отдела определить суммарную зарплату с учетом комиссионных


SELECT department_id, SUM (salary* (1+NVL (commission_pct,0)))

As sum_sal

FROM Employees

GROUP BY department_id

ORDER BY department_id;



Пример 4.9. Для каждого отдела определить суммарную длину имен (столбца first_name)


SELECT department_id, SUM (LENGTH (first_name)) As sum_f_nam

FROM Employees

GROUP BY department_id

ORDER BY department_id;



Группировка по нескольким столбцам


В предложении GROUP BY можно указать несколько столбцов. В этом случае группу образуют строки с совпадающими значениями всех столбцов, по которым осуществляется группировка. Рассмотрим задачи, в которых требуется группировка по нескольким столбцам.

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


Пример 4.10а. Для каждого отдела определить должности и количество сотрудников, занимающих эту должность (содержит ошибку)


SELECT department_id, job_id, count (*)

FROM employees

GROUP BY department_id;


Причина ошибки: при наличии группировки предложение SELECT может содержать только столбцы, по которым осуществляется группировка и агрегатные функции.


Пример 4.10б. Для отделов 30 и 50 определить должности и количество сотрудников, занимающих каждую должность


SELECT department_id, job_id, count (*)

FROM Employees

WHERE department_id IN (30,50)

GROUP BY department_id, job_id

ORDER BY department_id;



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


SELECT department_id, rating_e, count (*),sum (salary)

FROM Employees

WHERE department_id <= 50

GROUP BY department_id, rating_e

ORDER BY department_id;



Использование условий на группу


Условия на группу указываются в предложении HAVING.


Пример 4.12. Вывести суммарную зарплату для тех отделов, у которых суммарная зарплата превышает 50 000

SELECT department_id, SUM (salary)

FROM Employees

GROUP BY department_id

HAVING SUM (salary)> 50000;



Условие выборки может быть проверено до группировки. В этом случае сначала выбираются строки, удовлетворяющие условию, а потом осуществляется группировка полученных данных. Для полученных групп можно указать условие в предложении HAVING. В результат запроса попадут только те группы, которые удовлетворяют этому условию.


Пример 4.13. Вывести должности и количество сотрудников, которые получают зарплату более 10 000


SELECT department_id, SUM (salary)

FROM Employees

GROUP BY department_id

HAVING SUM (salary)> 50000;



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


Пример 4.14. Вывести должности и количество сотрудников, которые получают зарплату более 10 000, которые занимают более одного сотрудника, упорядочив их в порядке убывания количества сотрудников

SELECT job_id, COUNT (*) As num_job

FROM Employees

WHERE salary> 10000

GROUP BY job_id

HAVING COUNT (*)> 1

ORDER BY num_job DESC;



Пример 4.15. Вывести номера отделов, у которых число сотрудников, имеющих рейтинг 5, больше одного, количество сотрудников, имеющих рейтинг 5, и их суммарную зарплату


SELECT department_id, rating_e, count (*),sum (salary)

FROM Employees

WHERE rating_e = 5

GROUP BY department_id, rating_e

HAVING count (*)> 1

ORDER BY department_id;


Использование вложенных агрегатных функций

Хотя Oracle и допускает использование вложенных агрегатных функций, но только на один уровень и только в предложении SELECT. При этом предложение SELECT не должно содержать других элементов.


Пример 4.16. Определить количество сотрудников в каждом отделе


SELECT department_id, count (*)

FROM Employees

GROUP BY department_id

ORDER BY department_id;



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


Пример 4.17. Найти максимальное число сотрудников работающих в одном отделе


SELECT Max (COUNT (*))

FROM Employees

GROUP BY department_id;



Но вложенные агрегатные функции нельзя использовать в предложениях WHERE и HAVING, поэтому для того, чтобы найти отдел, в котором работает максимальное число сотрудников, понадобится использование подзапроса.


Пример 4.18. Найти отдел, в котором работает максимальное число сотрудников.

SELECT department_id, COUNT (*)

FROM Employees

GROUP BY department_id

HAVING COUNT (*) =

(SELECT MAX (COUNT (*))

FROM Employees

GROUP BY department_id);


Использование специальных операторов группировки

Рассмотрим специальные операторы группировки и функции, которые позволяют существенно расширить возможности запросов с группировкой данных.

Оператор GROUP BY ROLLUP

Расширяет возможности GROUP BY, возвращая для каждой группы строку, содержащую итоги по группе, а также строку, содержащую общий итог для всех групп, и имеет следующий вид:

GROUP BY ROLLUP {список столбцов}

Для демонстрации возможностей, которые предоставляет оператор GROUP BY ROLLUP, рассмотрим следующую задачу: для каждого отдела определить должности и количество сотрудников, занимающих эту должность. Решение этой задачи без использования ROLLUP содержится в примере 4.10.

Пример 4.19. Для отделов 30 и 50 определить должности и количество сотрудников, занимающих эту должность

SELECT department_id, job_id, count (*)

FROM Employees

WHERE department_id IN (30,50)

GROUP BY ROLLUP (department_id, job_id)

ORDER BY department_id;


По сравнению с результатами, которые выводит запрос из примера 4.10, этот запрос выводит данные о количестве сотрудников в каждом отделе и общем количестве сотрудников, работающих в рассматриваемых отделах.

В условия группировки можно добавить столбец rating_e.


Пример 4.20. Для отделов 30 и 50 определить должности, рейтинг и количество сотрудников, занимающих каждую должность и имеющих определенный рейтинг


SELECT department_id, job_id, rating_e, count (*)

FROM Employees

WHERE department_id IN (30,50)

GROUP BY ROLLUP (department_id, job_id, rating_e)

ORDER BY department_id;



Оператор GROUP BY CUBE


Возвращает предварительные итоги для всех комбинаций столбцов и строку с общим итогом и имеет следующий вид:


GROUP BY CUBE {список столбцов}

Рассмотрим решение предыдущих задач с использованием этого оператора.


Пример 4.21. Для отделов 30 и 50 определить должности и количество сотрудников, занимающих каждую должность


SELECT department_id, job_id, count (*)

FROM Employees

WHERE department_id IN (30,50)

GROUP BY CUBE (department_id, job_id)

ORDER BY department_id;



Сравнивая эти результаты с результатами из примера 4.19, можно увидеть, что результат последнего запроса содержит данные о количестве сотрудников, занимающих определенную должность, без учета отдела, в котором они работают.

В примере 4.22 приведен вариант решения задачи из примера 4.20 с использованием оператора GROUP BY CUBE.


Пример 4.22. Для отделов 30 и 50 определить должности, рейтинг и количество сотрудников, занимающих каждую должность и рейтинг и имеющих рейтинг> 3

Конец ознакомительного фрагмента.

1
...