Раздел 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

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

NYearNQuarterCntПояснения
2003187Число заказов за I квартал
2003277Число заказов за II квартал
2003391Число заказов за III квартал
20044125Число заказов за IV квартал
20041139Число заказов за I квартал
20042119Число заказов за II квартал

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

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

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

NYearNQuarterCntПояснения
NULLNULL648Общее число заказов
2003NULL380Общее число заказов за 2003
2003187Число заказов за I квартал
2003277Число заказов за II квартал
2003391Число заказов за III квартал
20034125Число заказов за IV квартал
2004NULL268Общее число заказов за 2004
20041139Число заказов за I квартал
20042119Число заказов за II квартал

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

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

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

NYearNQuarterCntПояснения
NULLNULL648Общее число заказов
NULL1226Число заказов за I квартал за все годы
NULL2296Число заказов за II квартал за все годы
NULL3101Число заказов за III квартал за все годы
NULL4125Число заказов за IV квартал за все годы
2003NULL380Общее число заказов за 2003
2003187Число заказов за I квартал
2003277Число заказов за II квартал
2003391Число заказов за III картал
20034125Число заказов за IV картал
2004NULL268Общее число заказов за 2004
20041139Число заказов за I квартал
20042119Число заказов за 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:

NYearNQuarterCntПояснения
2003NULL380Общее число заказов за 2003
2003187Число заказов за I квартал
2003277Число заказов за II квартал
2003391Число заказов за III квартал
20034125Число заказов за IV квартал
2004NULL268Общее число заказов за 2004
20041139Число заказов за I квартал
20042119Число заказов за 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)


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




Статистика