Databases. Part XII «Группировки & агрегаты»

Databases. Part XII «Группировки & агрегаты»

Написание запросов редко ограничивается простым выбором строк из таблиц, соответствующих каким-либо условиям. Гораздо чаще, задача состоит в том, чтобы получить какие-то статистические данные, просто посчитать, либо задать условия отбора для итогов сделанной калькуляции. Поэтому, данная тема посвящена групповым запросам и всем что с ними связано...

Внешний вид группового запроса обычно такой:

Короче говоря, если в запросе есть GROUP BY, то так и знайте – это групповой запрос. Поверили?? :D На самом деле все не так :no: В групповом запросе может и не быть группировки... Тогда подсчет производится по всей таблице.

А вот на вопрос, когда же запрос групповой, можно ответить так – когда в запросе есть агрегативные функции, которые я в названии темы обозвал «агрегатами». Агрегат – это итоговая функция, применяемая к полю, например:

COUNT() – количество

SUM() – сумма

AVG() – среднее значение

MIN() – минимум

MAX() – максимум

Теперь несколько замечаний:

1. Агрегат можно применить только к полю (это значит, что агрегат можно применить только к полю)

2. Все поля выбора, к которым не применен агрегат, должны участвовать в группировке (также как если поле не участвует в группировке, на него должен быть наложен агрегат)

3. В групповом запросе должны выбираться только те поля, по которым производится группировка, либо подсчитываются итоги с помощью агрегатов (а это значит, что в <select_list> звездочку ставить нельзя)

Вот и вся теория :) Порешаем примерчики??

Начнем с простого :whistle: Попробуем посчитать количество сотрудников в каждом отделе. Сразу видно, что раз речь идет про «посчитать», то агрегат будет наложен на поле, которое идентифицирует сотрудника. А считать нужно в каждом отделе, поэтому их нужно всех загнать в свои кабинеты, и только потом пересчитывать на поле «отдел» будет наложена группировка. Запрос будет выглядеть так:

SELECT Код_отдела, COUNT(Код_сотрудника) AS Количество_сотрудников

FROM Сотрудники

GROUP BY Код_отдела

Еще раз обращу внимание, что код отдела участвует в группировке, поэтому на все остальные поля, в нашем случае только на код сотрудника, наложен агрегат. В запросе это COUNT, так как считаем количество.

Как это работает:

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

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

SELECT Название_отдела, COUNT(Код_сотрудника) AS Количество_сотрудников

FROM Сотрудники INNER JOIN Отделы ON Сотрудники. Код_отдела=Отделы. Код_отдела

GROUP BY Название_отдела

Пример следующий. Дана таблица:

Посчитаем, сколько упаковок просроченного товара находится на каждом складе:

SELECT Номер_скалада, SUM(Количество_упаковок) AS Количество_упаковок

FROM Размещение_товаров

WHERE DATEADD(“d”,Срок_годности, Дата_приема)<NOW()

GROUP BY Номер_склада

От предыдущего этот запрос отличается тем, что здесь считается суммарное количество упаковок, и поэтому наложен другой агрегат. А еще сказано, что считаем только просроченные упаковки, следовательно, прибавив к дате приема срок годности, мы должны получить дату до сегодняшнего дня, что обеспечивают встроенные функции DATEADD и NOW и операция отношения «меньше».


Карта сайта


Информационный сайт Webavtocat.ru