Поиск…


Вступление

Результаты запроса 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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow