Поиск…
Вступление
Результаты запроса SELECT можно сгруппировать по одному или нескольким столбцам с помощью оператора GROUP BY
: все результаты с одинаковым значением в сгруппированных столбцах агрегируются вместе. Это генерирует таблицу частичных результатов вместо одного результата. GROUP BY может использоваться совместно с функциями агрегации с использованием оператора HAVING
для определения того, как агрегируются негрупповые столбцы.
Синтаксис
ГРУППА ПО {
Колонка выражение
| ROLLUP (<group_by_expression> [, ... n])
| CUBE (<group_by_expression> [, ... n])
| ГРУППОВЫЕ НАБОРЫ ([, ... n])
| () - вычисляет общую сумму
} [, ... n]<group_by_expression> :: =
Колонка выражение
| (column-expression [, ... n])<grouping_set> :: =
() - вычисляет общую сумму
| <Grouping_set_item>
| (<grouping_set_item> [, ... n])<grouping_set_item> :: =
<Group_by_expression>
| ROLLUP (<group_by_expression> [, ... n])
| CUBE (<group_by_expression> [, ... n])
ИСПОЛЬЗУЙТЕ GROUP BY, чтобы указать количество строк для каждой уникальной записи в данном столбце
Предположим, вы хотите генерировать подсчеты или промежуточные итоги для заданного значения в столбце.
Учитывая эту таблицу, «Вестеросианцы»:
название | GreatHouseAllegience |
---|---|
Arya | застывший |
Cercei | Lannister |
Myrcella | Lannister |
Yara | Грейджый |
Catelyn | застывший |
Sansa | застывший |
Без GROUP BY COUNT просто вернет общее количество строк:
SELECT Count(*) Number_of_Westerosians
FROM Westerosians
возвращается ...
Number_of_Westerosians |
---|
6 |
Но добавив GROUP BY, мы можем ЗАПИСАТЬ пользователей для каждого значения в данном столбце, чтобы вернуть число людей в данном Великом Доме, скажем:
SELECT GreatHouseAllegience House, Count(*) Number_of_Westerosians
FROM Westerosians
GROUP BY GreatHouseAllegience
возвращается ...
жилой дом | Number_of_Westerosians |
---|---|
застывший | 3 |
Грейджый | 1 |
Lannister | 2 |
Обычно для объединения результатов GROUP BY с ORDER BY можно сортировать результаты по самой большой или наименьшей категории:
SELECT GreatHouseAllegience House, Count(*) Number_of_Westerosians
FROM Westerosians
GROUP BY GreatHouseAllegience
ORDER BY Number_of_Westerosians Desc
возвращается ...
жилой дом | Number_of_Westerosians |
---|---|
застывший | 3 |
Lannister | 2 |
Грейджый | 1 |
Результаты фильтрации GROUP BY с использованием предложения HAVING
Предложение HAVING фильтрует результаты выражения GROUP BY. Примечание. В следующих примерах используется база данных примеров библиотеки .
Примеры:
Верните всех авторов, написавших более одной книги ( живой пример ).
SELECT
a.Id,
a.Name,
COUNT(*) BooksWritten
FROM BooksAuthors ba
INNER JOIN Authors a ON a.id = ba.authorid
GROUP BY
a.Id,
a.Name
HAVING COUNT(*) > 1 -- equals to HAVING BooksWritten > 1
;
Верните все книги, в которых есть более трех авторов ( живой пример ).
SELECT
b.Id,
b.Title,
COUNT(*) NumberOfAuthors
FROM BooksAuthors ba
INNER JOIN Books b ON b.id = ba.bookid
GROUP BY
b.Id,
b.Title
HAVING COUNT(*) > 3 -- equals to HAVING NumberOfAuthors > 3
;
Пример базовой GROUP BY
Это может быть проще, если вы думаете о GROUP BY как «для каждого» для объяснения. Запрос ниже:
SELECT EmpID, SUM (MonthlySalary)
FROM Employee
GROUP BY EmpID
говорит:
«Дайте мне сумму MonthlySalary для каждого EmpID»
Поэтому, если ваша таблица выглядит так:
+-----+-------------+
|EmpID|MonthlySalary|
+-----+-------------+
|1 |200 |
+-----+-------------+
|2 |300 |
+-----+-------------+
Результат:
+-+---+
|1|200|
+-+---+
|2|300|
+-+---+
Сумма не будет ничего делать, потому что сумма одного числа - это число. С другой стороны, если бы это выглядело так:
+-----+-------------+
|EmpID|MonthlySalary|
+-----+-------------+
|1 |200 |
+-----+-------------+
|1 |300 |
+-----+-------------+
|2 |300 |
+-----+-------------+
Результат:
+-+---+
|1|500|
+-+---+
|2|300|
+-+---+
Тогда это будет потому, что есть два EmpID 1 для суммирования.
Агрегация ROLAP (интеллектуальный анализ данных)
Описание
Стандарт SQL предоставляет два дополнительных оператора агрегата. Они используют полиморфное значение «ALL» для обозначения набора всех значений, которые может принимать атрибут. Двумя операторами являются:
-
with data cube
что он предоставляет все возможные комбинации, чем атрибуты аргумента этого предложения. -
with roll up
что он обеспечивает агрегаты, полученные путем рассмотрения атрибутов в порядке слева направо, по сравнению с тем, как они перечислены в аргументе предложения.
Стандартные версии SQL, поддерживающие эти функции: 1999,2003,2006,2008,2011.
Примеры
Рассмотрим эту таблицу:
питание | марка | Итого |
---|---|---|
Макаронные изделия | Brand1 | 100 |
Макаронные изделия | brand2 | 250 |
Пицца | brand2 | 300 |
С кубом
select Food,Brand,Total_amount
from Table
group by Food,Brand,Total_amount with cube
питание | марка | Итого |
---|---|---|
Макаронные изделия | Brand1 | 100 |
Макаронные изделия | brand2 | 250 |
Макаронные изделия | ВСЕ | 350 |
Пицца | brand2 | 300 |
Пицца | ВСЕ | 300 |
ВСЕ | Brand1 | 100 |
ВСЕ | brand2 | 550 |
ВСЕ | ВСЕ | 650 |
С рулоном
select Food,Brand,Total_amount
from Table
group by Food,Brand,Total_amount with roll up
питание | марка | Итого |
---|---|---|
Макаронные изделия | Brand1 | 100 |
Макаронные изделия | brand2 | 250 |
Пицца | brand2 | 300 |
Макаронные изделия | ВСЕ | 350 |
Пицца | ВСЕ | 300 |
ВСЕ | ВСЕ | 650 |