Раздел GROUP BY при составлении запроса в SQL

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

Синтаксическая форма
GROUP BY [{ROLLUP|CUBE|GROUPING SET}] (<список столбцов>) [HAVING <предикат>]

Примечания
При группировании следует учитывать следующие ограничения и особенности:
• Нельзя группировать строки по вычисляемым столбцам.
• Если в столбце, по которому производится группирование, существуют NULL-значения, то все они следуют в зависимости от СУБД в конце или в начале множества выходных строк.
• Возвращаемым столбцом может быть:
— Константа
— Функция агрегирования, возвращающая одно значения для всех строк группы
— Столбец (столбцы), по которому производится группирование
— Выражение, включающее перечисленные выше элементы

Примеры на группирование

SELECT SNum, MAX(Amt) FROM Orders GROUP BY SNum
SELECT SNum, Odate, MAX(Amt) AS MaxAmt FROM Orders GROUP BY SNum, Odate
SELECT SNum, Odate, MAX(Amt) FROM Orders WHERE Odate>10/03/1990 GROUP BY SNum, Odate

4) Варианты группирования
4.1) <список столбцов>
Например:

SELECT NYear, NQuarter, COUNT(*) AS Cnt FROM Orders GROUP BY NYear, NQuanter ORDER BY NYear, NQuarter

Результат группирования по списку столбцов:

NYear NQuarter Cnt Пояснения
2003 1 87 Число заказов за I квартал
2003 2 77 Число заказов за II квартал
2003 3 91 Число заказов за III квартал
2004 4 125 Число заказов за IV квартал
2004 1 139 Число заказов за I квартал
2004 2 119 Число заказов за II квартал

4.2) ROLLUP (<список столбцов>)
С ROLLUP обеспечивается вывод:
— Первоначально общих итогов
— Затем итогов по группам
— А после итогов каждой группы выводятся значения колонок, входящие в группу.

SELECT NYear, NQuarter, COUNT(*) AS Cnt FROM Orders GROUP BY ROLLUP(NYear, NQuarter) ORDER BY NYear, NQuarter

Результат группирования ROLLUP:

NYear NQuarter Cnt Пояснения
NULL NULL 648 Общее число заказов
2003 NULL 380 Общее число заказов за 2003
2003 1 87 Число заказов за I квартал
2003 2 77 Число заказов за II квартал
2003 3 91 Число заказов за III квартал
2003 4 125 Число заказов за IV квартал
2004 NULL 268 Общее число заказов за 2004
2004 1 139 Число заказов за I квартал
2004 2 119 Число заказов за II квартал

4.3) CUBE (<список столбцов>)
CUBE дополнительно к ROLLUP обеспечивает вывод после общих итогов еще и итогов одной колонки группирования по второй.

SELECT NYear, NQuarter, COUNT(*) AS Cnt FROM Orders GROUP BY CUBE(NYear, NQuarter) ORBER BY NYear, NQuarter

Результат группирования CUBE:

NYear NQuarter Cnt Пояснения
NULL NULL 648 Общее число заказов
NULL 1 226 Число заказов за I квартал за все годы
NULL 2 296 Число заказов за II квартал за все годы
NULL 3 101 Число заказов за III квартал за все годы
NULL 4 125 Число заказов за IV квартал за все годы
2003 NULL 380 Общее число заказов за 2003
2003 1 87 Число заказов за I квартал
2003 2 77 Число заказов за II квартал
2003 3 91 Число заказов за III картал
2003 4 125 Число заказов за IV картал
2004 NULL 268 Общее число заказов за 2004
2004 1 139 Число заказов за I квартал
2004 2 119 Число заказов за II квартал

4.4) GROUPING SET (<список столбцов>)
GROUPING SETS позволяет проводить агрегацию по нескольким группам в одном запросе. Для каждого набора групп запрос возвращает промежуточные итоги, где значение столбца группировки равно NULL. Фактически не выводит общих итогов по сравнению с ROLLUP.

SELECT NYear, NQuarter, COUNT(*) AS Cnt FROM Orders GROUP BY GROUNING SET((NYear, NQuarter),(NYear)) ORDER BY NYear, NQuarter

Результат группирования GROUPING SET:

NYear NQuarter Cnt Пояснения
2003 NULL 380 Общее число заказов за 2003
2003 1 87 Число заказов за I квартал
2003 2 77 Число заказов за II квартал
2003 3 91 Число заказов за III квартал
2003 4 125 Число заказов за IV квартал
2004 NULL 268 Общее число заказов за 2004
2004 1 139 Число заказов за I квартал
2004 2 119 Число заказов за II квартал

5) Подраздел HAVING
Этот подраздел предназначен для ограничения числа строк в сгруппированной таблице и является частью раздела GROUP BY. Предикат этого раздела строится по тем же семантическим правилам, что и в разделе WHERE, однако напрямую в предикате могут участвовать только те столбцы, которые указаны в раздел GROUP BY. Остальные можно использовать только внутри функций агрегирования.

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

Примеры для подраздела HAVING:

SELECT SNum, Odate, MAX(Amt) FROM Orders GROUP BY SNum, Odate HAVING MAX(Amt)>3000
SELECT SNum, MAX(Amt) FROM Orders GROUP BY SNum HAVING SNum IN (1002, 1007)
SELECT Rating, COUNT (DISTINCT CNum) FROM Customer GROUP BY Rating HAVING Rating>(SELECT AVG(Rating) FROM Customer WHERE City=’San Jose’)
SELECT Odate, SUM(Amt) FROM Orders A GROUP BY Odate HAVING SUM(Amt)>(SELECT 2000+MIN(Amt) FROM Orders B WHERE A.Odate=B.Odate)


Комментарии запрещены.





Статистика

Рейтинг@Mail.ru