Бөлісу құралы:


SELECT — предложение GROUP BY (Transact-SQL)

Применимо к:SQL ServerБаза данных Azure SQLУправляемый экземпляр Azure SQLAzure Synapse AnalyticsСистема платформы аналитики (PDW)Конечная точка SQL аналитики в Microsoft FabricХранилище в Microsoft FabricБаза данных SQL в Microsoft Fabric

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

Syntax

Соглашения о синтаксисе Transact-SQL

Синтаксис для SQL Server и Базы данных SQL Azure:

-- ISO-Compliant Syntax

GROUP BY {
      column-expression
    | ROLLUP ( <group_by_expression> [ , ...n ] )
    | CUBE ( <group_by_expression> [ , ...n ] )
    | GROUPING SETS ( <grouping_set> [ , ...n ]  )
    | () --calculates the grand total
} [ , ...n ]

<group_by_expression> ::=
      column-expression
    | ( column-expression [ , ...n ] )

<grouping_set> ::=
      () --calculates the grand total
    | <grouping_set_item>
    | ( <grouping_set_item> [ , ...n ] )

<grouping_set_item> ::=
      <group_by_expression>
    | ROLLUP ( <group_by_expression> [ , ...n ] )
    | CUBE ( <group_by_expression> [ , ...n ] )

-- For backward compatibility only.
-- Non-ISO-Compliant Syntax for SQL Server and Azure SQL Database

GROUP BY {
       ALL column-expression [ , ...n ]
    | column-expression [ , ...n ]  WITH { CUBE | ROLLUP }
       }

Синтаксис Для Azure Synapse Analytics:

GROUP BY {
      column-name [ WITH (DISTRIBUTED_AGG) ]
    | column-expression
    | ROLLUP ( <group_by_expression> [ , ...n ] )
} [ , ...n ]

Синтаксис для системы платформы аналитики (PDW):

GROUP BY {
      column-name [ WITH (DISTRIBUTED_AGG) ]
    | column-expression
} [ , ...n ]

Arguments

column-expression

Указывает на столбец или на нестатистическое вычисление в столбце. Этот столбец может принадлежать таблице, производной таблице или представлению. Столбец должен отображаться в FROM предложении инструкции SELECT , но не нужно отображаться в списке SELECT .

Допустимые выражения см. в разделе expression.

Столбец должен отображаться в FROM предложении инструкции SELECT , но не требуется отображаться в списке SELECT . Однако каждый столбец таблицы или представления в любом негрегрегатном выражении в списке <select>GROUP BY должен быть включен в список.

Следующие инструкции являются допустимыми.

SELECT ColumnA,
       ColumnB
FROM T
GROUP BY ColumnA, ColumnB;

SELECT ColumnA + ColumnB
FROM T
GROUP BY ColumnA, ColumnB;

SELECT ColumnA + ColumnB
FROM T
GROUP BY ColumnA + ColumnB;

SELECT ColumnA + ColumnB + constant
FROM T
GROUP BY ColumnA, ColumnB;

Следующие инструкции не допускаются.

SELECT ColumnA,
       ColumnB
FROM T
GROUP BY ColumnA + ColumnB;

SELECT ColumnA + constant + ColumnB
FROM T
GROUP BY ColumnA + ColumnB;

Выражение столбца не может содержать следующее:

  • Псевдоним столбца, который определяется в списке SELECT . Он может использовать псевдоним столбца для производной таблицы, определенной в предложении FROM .
  • столбец типа text, ntext, или image. Однако столбец типа text, ntext или image можно использовать как аргумент для функции, возвращающей значение допустимого типа данных. Например, выражение может использовать SUBSTRING() и CAST(). Это правило также относится к выражениям в предложении HAVING .
  • методы типа данных xml. Сюда может входить определяемой пользователем функции, которая использует методы типа данных xml. Сюда может входить вычисляемый столбец, который использует методы типа данных xml.
  • Подзапрос. Возвращается ошибка 144.
  • столбец из индексированного представления.

ВЫРАЖЕНИЕ СТОЛБЦА GROUP BY [ ,... n ]

SELECT Группирует результаты инструкции в соответствии со значениями в списке одного или нескольких выражений столбцов.

Например, этот запрос создает таблицу Sales со столбцами для Region, Territoryа также Sales. Она вставляет четыре строки и две строки имеют соответствующие значения для Region и Territory.

CREATE TABLE Sales
(
    Region VARCHAR (50),
    Territory VARCHAR (50),
    Sales INT
);
GO

INSERT INTO Sales VALUES (N'Canada', N'Alberta', 100);
INSERT INTO Sales VALUES (N'Canada', N'British Columbia', 200);
INSERT INTO Sales VALUES (N'Canada', N'British Columbia', 300);
INSERT INTO Sales VALUES (N'United States', N'Montana', 100);

Таблица Sales содержит следующие строки:

Region Территория Sales
Canada Alberta 100
Canada Британская Колумбия 200
Canada Британская Колумбия 300
United States Montana 100

Следующий запрос группирует Region и Territory возвращает агрегатную сумму для каждого сочетания значений.

SELECT Region,
       Territory,
       SUM(sales) AS TotalSales
FROM Sales
GROUP BY Region, Territory;

Результат запроса имеет три строки, так как существует три сочетания значений для Region и Territory. Для TotalSales Канады и Британской Колумбии сумма двух строк.

Region Территория TotalSales
Canada Alberta 100
Canada Британская Колумбия 500
United States Montana 100

СГРУППИРОВАТЬ ПО СВЕРТКИ

Создает группу для каждого сочетания выражений столбцов. Кроме того, выполняет сведение результатов в промежуточные и общие итоги. Для этого он перемещается справа налево, уменьшая количество выражений столбцов, над которыми он создает группы и агрегаты.

Порядок столбцов влияет на ROLLUP выходные данные и может повлиять на количество строк в результирующем наборе.

Например, GROUP BY ROLLUP (col1, col2, col3, col4) создает группы для каждого сочетания выражений столбцов в следующих списках:

  • COL1, COL2, COL3, COL4
  • col1, col2, col3, NULL
  • col1, col2, NULL, NULL
  • col1, NULL, NULL, NULL, NULL
  • NULL, NULL, NULL, NULL (это общий итог)

Используя таблицу из предыдущего примера, этот код выполняет GROUP BY ROLLUP операцию вместо простого GROUP BY.

SELECT Region,
       Territory,
       SUM(Sales) AS TotalSales
FROM Sales
GROUP BY ROLLUP(Region, Territory);

Результат запроса имеет те же агрегаты, что и простые GROUP BY без ROLLUP. Кроме того, он создает промежуточные итоги для каждого значения региона. Наконец, выводится общий итог для всех строк. Результат выглядит следующим образом.

Region Территория TotalSales
Canada Alberta 100
Canada Британская Колумбия 500
Canada NULL 600
United States Montana 100
United States NULL 100
NULL NULL 700

GROUP BY CUBE ()

GROUP BY CUBE создает группы для всех возможных сочетаний столбцов. Для GROUP BY CUBE (a, b)результатов имеются группы для уникальных значений (a, b), (NULL, b)и (a, NULL)(NULL, NULL).

Используя таблицу из предыдущих примеров, этот код выполняет GROUP BY CUBE операцию в регионе и территории.

SELECT Region,
       Territory,
       SUM(Sales) AS TotalSales
FROM Sales
GROUP BY CUBE(Region, Territory);

Результат запроса содержит группы для уникальных значений (Region, Territory), (NULL, Territory)(Region, NULL)а (NULL, NULL)также . Результат выглядит следующим образом:

Region Территория TotalSales
Canada Alberta 100
NULL Alberta 100
Canada Британская Колумбия 500
NULL Британская Колумбия 500
United States Montana 100
NULL Montana 100
NULL NULL 700
Canada NULL 600
United States NULL 100

GROUP BY GROUPING SETS ()

Параметр GROUPING SETS объединяет несколько GROUP BY предложений в одно GROUP BY предложение. Результаты совпадают с использованием UNION ALL указанных групп.

Например, GROUP BY ROLLUP (Region, Territory) и GROUP BY GROUPING SETS ( ROLLUP (Region, Territory)) возвращают одинаковые результаты.

При GROUPING SETS наличии двух или более элементов результаты являются объединением элементов. В этом примере возвращается объединение ROLLUP и CUBE результаты для региона и территории.

SELECT Region,
       Territory,
       SUM(Sales) AS TotalSales
FROM Sales
GROUP BY GROUPING SETS(ROLLUP(Region, Territory), CUBE(Region, Territory));

Результаты совпадают с этим запросом, который возвращает объединение двух GROUP BY операторов.

SELECT Region,
       Territory,
       SUM(Sales) AS TotalSales
FROM Sales
GROUP BY ROLLUP(Region, Territory)
UNION ALL
SELECT Region,
       Territory,
       SUM(Sales) AS TotalSales
FROM Sales
GROUP BY CUBE(Region, Territory);

SQL не объединяет повторяющиеся группы, созданные GROUPING SETS для списка. Например, в GROUP BY ((), CUBE (Region, Territory))обоих элементах возвращается строка для большого итога, а обе строки отображаются в результатах.

ГРУППА ПО ()

Указывает пустую группу, которая создает общий итог. Эта группа полезна в качестве одного из элементов GROUPING SET. Например, это заявление дает общий объем продаж для каждого региона, а затем дает общий итог для всех регионов.

SELECT Region,
       SUM(Sales) AS TotalSales
FROM Sales
GROUP BY GROUPING SETS(Region, ());

ВЫРАЖЕНИЕ СТОЛБЦА GROUP BY ALL [ ,... n ]

Применимо к: SQL Server и Azure SQL Database

Note

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

Указывает, следует ли включать все группы в результаты независимо от того, соответствуют ли они критериям поиска в предложении WHERE . Группы, которые не соответствуют критериям поиска, имеют NULL агрегирование.

GROUP BY ALL:

  • Не поддерживается в запросах, обращаюющихся к удаленным таблицам, если в запросе также WHERE есть предложение.
  • Завершается сбоем в столбцах с атрибутом FILESTREAM.

ВЫРАЖЕНИЕ СТОЛБЦА GROUP BY [ ,... n ] WITH { CUBE | ROLLUP }

Применимо к: SQL Server и Azure SQL Database

Note

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

С (DISTRIBUTED_AGG)

Область применения: Azure Synapse Analytics и система платформы аналитики (PDW)

Указание DISTRIBUTED_AGG запроса заставляет систему массово параллельной обработки (MPP) распространять таблицу в определенном столбце перед выполнением агрегирования. Только один столбец в предложении GROUP BY может содержать DISTRIBUTED_AGG указание запроса. После завершения запроса перераспределенная таблица удаляется. Исходная таблица не изменяется.

Note

Указание DISTRIBUTED_AGG запроса предоставляется для обеспечения обратной совместимости с более ранними версиями платформы Аналитики (PDW) и не повышает производительность большинства запросов. По умолчанию MPP уже перераспределяет данные для улучшения производительности для статистических вычислений.

Замечания

Взаимодействие GROUP BY с инструкцией SELECT

SELECT Список:

  • Векторные агрегаты. Если в SELECT список включены агрегатные функции, GROUP BY вычисляется сводное значение для каждой группы. Эти функции называются агрегатами векторов.
  • Чёткие агрегаты. Агрегаты AVG(DISTINCT <column_name>), COUNT(DISTINCT <column_name>)а также SUM(DISTINCT <column_name>) работа с ROLLUP, CUBEа также GROUPING SETS.

Предложение WHERE:

  • SQL удаляет строки, которые не соответствуют условиям в WHERE предложении перед выполнением каких-либо операций группировки.

Предложение HAVING:

  • SQL использует HAVING предложение для фильтрации групп в результирующем наборе.

Предложение ORDER BY:

  • ORDER BY Используйте предложение, чтобы упорядочить результирующий набор. Предложение GROUP BY не упорядочиет результирующий набор.

NULL Значения:

  • Если столбец группировки содержит NULL значения, все NULL значения считаются равными и собираются в одну группу.

Ограничения

Область применения: SQL Server и Azure Synapse Analytics

Максимальная емкость

GROUP BY Для предложения, использующего ROLLUP(CUBEилиGROUPING SETS) максимальное число выражений, равное 32. Максимальное число групп — 4096 (212). В следующих примерах происходит сбой, так как предложение GROUP BY содержит более 4096 групп.

  • Следующий пример создает наборы группирования 4097 (212 + 1), а затем завершается сбоем.

    GROUP BY GROUPING SETS( CUBE(a1, ..., a12), b)
    
  • В следующем примере создается 4097 (212 + 1) групп, а затем завершается сбоем. Оба CUBE ()() набора группирования создают большую общую строку и повторяющиеся наборы группирования не устраняются.

    GROUP BY GROUPING SETS( CUBE(a1, ..., a12), ())
    
  • В этом примере используется синтаксис с обратной совместимостью. Он создает наборы группирования 8 192 (213), а затем завершается сбоем.

    GROUP BY CUBE (a1, ..., a13)
    GROUP BY a1, ..., a13 WITH CUBE
    

    Для предложений с обратной совместимостью GROUP BY , которые не содержат CUBE или ROLLUPколичество GROUP BY элементов ограничено GROUP BY размерами столбцов, агрегированными столбцами и статистическими значениями, участвующими в запросе. Это ограничение исходит от ограничения в 8 060 байтов промежуточной рабочей области, содержащей промежуточные результаты запроса. При указании или CUBEROLLUP указано не более 12 выражений группирования.

Поддержка функций предложения GROUP BY, совместимых с ISO и ANSI SQL-2006

Предложение GROUP BY поддерживает все GROUP BY функции, включенные в стандарт SQL-2006 со следующими исключениями синтаксиса:

  • Группирование наборов не допускается в GROUP BY предложении, если они не являются частью явного GROUPING SETS списка. Например, GROUP BY Column1, (Column2, ...ColumnN) допускается в стандарте, но не в Transact-SQL. Transact-SQL поддерживает GROUP BY C1, GROUPING SETS ((Column2, ...ColumnN)) и GROUP BY Column1, Column2, ... ColumnN, которые семантически эквивалентны. Эти предложения семантически эквивалентны предыдущему GROUP BY примеру. Это ограничение позволяет избежать возможности, которая GROUP BY Column1, (Column2, ...ColumnN) может быть неправильно интерпретирована как GROUP BY C1, GROUPING SETS ((Column2, ...ColumnN)), которая не является семантически эквивалентной.

  • Группирование наборов не допускается внутри группирования наборов. Например, предложение GROUP BY GROUPING SETS (A1, A2,...An, GROUPING SETS (C1, C2, ...Cn)) допускается в стандарте SQL-2006, но не в Transact-SQL. Transact-SQL допускает GROUP BY GROUPING SETS( A1, A2,...An, C1, C2, ...Cn) или GROUP BY GROUPING SETS( (A1), (A2), ... (An), (C1), (C2), ... (Cn))семантически эквивалентно первому GROUP BY примеру и имеет более четкий синтаксис.

  • GROUP BY ALL и GROUP BY DISTINCT допускается только в простом GROUP BY предложении, содержащее выражения столбцов. Их нельзя использовать с GROUPING SETSконструкциями , или WITH CUBEROLLUPCUBEWITH ROLLUP конструкторами. ALL значение по умолчанию и неявно. Он также разрешен только в синтаксисе обратной совместимости.

Сравнение поддерживаемых GROUP BY функций

В следующей таблице описываются GROUP BY функции, поддерживаемые различными версиями SQL Server и уровнями совместимости базы данных.

Feature SQL Server Integration Services Уровень совместимости SQL Server — 100 или более
DISTINCT Агрегатов Не поддерживается для WITH CUBE или WITH ROLLUP. Поддерживается для WITH CUBE, , WITH ROLLUP, GROUPING SETSCUBEили ROLLUP.
Определяемая пользователем функция с CUBE именем или ROLLUP именем в предложении GROUP BY Определяемая пользователем функция dbo.cube(<arg1>, ...<argN>) или dbo.rollup(<arg1>, ...<argN>) в предложении GROUP BY разрешена.

Например: SELECT SUM (x) FROM T GROUP BY dbo.cube(y);
Определяемая пользователем функция dbo.cube (<arg1>, ...<argN>) или dbo.rollup(arg1>, ...<argN>) в предложении GROUP BY не разрешена.

Например: SELECT SUM (x) FROM T GROUP BY dbo.cube(y);

Возвращается сообщение об ошибке: "Неправильный синтаксис рядом с ключевым словом 'cube'|'rollup'".

Чтобы избежать этой проблемы, замените конструкцию dbo.cube на [dbo].[cube] или конструкцию dbo.rollup на [dbo].[rollup].

Следующий пример является допустимым: SELECT SUM (x) FROM T GROUP BY [dbo].[cube](y);.
GROUPING SETS Не поддерживается Supported
CUBE Не поддерживается Supported
ROLLUP Не поддерживается Supported
Общий итог, например GROUP BY() Не поддерживается Supported
GROUPING_ID функция Не поддерживается Supported
GROUPING функция Supported Supported
WITH CUBE Supported Supported
WITH ROLLUP Supported Supported
WITH CUBE или WITH ROLLUP "дубликат" удаление группирования Supported Supported

Examples

A. Использование базового предложения GROUP BY

В следующем примере извлекается сумма для каждого SalesOrderID из таблицы SalesOrderDetail. В примере используется база данных AdventureWorks.

SELECT SalesOrderID,
       SUM(LineTotal) AS SubTotal
FROM Sales.SalesOrderDetail AS sod
GROUP BY SalesOrderID
ORDER BY SalesOrderID;

B. Использование предложения GROUP BY с несколькими таблицами

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

SELECT a.City,
       COUNT(bea.AddressID) AS EmployeeCount
FROM Person.BusinessEntityAddress AS bea
     INNER JOIN Person.Address AS a
         ON bea.AddressID = a.AddressID
GROUP BY a.City
ORDER BY a.City;

C. Использование предложения GROUP BY в выражениях

В следующем примере показано, как извлечь данные об общем объеме продаж за каждый год с помощью функции DATEPART. Необходимо включить одно и то же выражение в SELECT список и GROUP BY предложение.

SELECT DATEPART(yyyy, OrderDate) AS N'Year',
       SUM(TotalDue) AS N'Total Order Amount'
FROM Sales.SalesOrderHeader
GROUP BY DATEPART(yyyy, OrderDate)
ORDER BY DATEPART(yyyy, OrderDate);

D. Использование предложения GROUP BY с предложением HAVING

В следующем примере используется HAVING предложение, чтобы указать, какие группы, созданные в GROUP BY предложении, должны быть включены в результирующий набор.

SELECT DATEPART(yyyy, OrderDate) AS N'Year',
       SUM(TotalDue) AS N'Total Order Amount'
FROM Sales.SalesOrderHeader
GROUP BY DATEPART(yyyy, OrderDate)
HAVING DATEPART(yyyy, OrderDate) >= N'2003'
ORDER BY DATEPART(yyyy, OrderDate);

Примеры: Azure Synapse Analytics и система платформы аналитики (PDW)

E. Базовое использование предложения GROUP BY

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

-- Uses AdventureWorksDW
SELECT OrderDateKey,
       SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey
ORDER BY OrderDateKey;

F. Базовое использование указания DISTRIBUTED_AGG

В этом примере используется указание запроса DISTRIBUTED_AGG для принудительного перетасовки таблицы в CustomerKey столбце перед выполнением агрегирования.

-- Uses AdventureWorksDW
SELECT CustomerKey,
       SUM(SalesAmount) AS sas
FROM FactInternetSales
GROUP BY CustomerKey WITH(DISTRIBUTED_AGG)
ORDER BY CustomerKey DESC;

G. Варианты синтаксиса для GROUP BY

Если в списке выборок нет агрегирования, необходимо включить каждый столбец в список выбора.GROUP BY Вы можете включить вычисляемые столбцы в список выбора, но их не требуется включать в GROUP BY список. В этих примерах показаны синтаксически допустимые SELECT операторы:

-- Uses AdventureWorks
SELECT LastName,
       FirstName
FROM DimCustomer
GROUP BY LastName, FirstName;
SELECT NumberCarsOwned
FROM DimCustomer
GROUP BY YearlyIncome, NumberCarsOwned;
SELECT (SalesAmount + TaxAmt + Freight) AS TotalCost
FROM FactInternetSales
GROUP BY SalesAmount, TaxAmt, Freight;
SELECT SalesAmount,
       SalesAmount * 1.10 AS SalesTax
FROM FactInternetSales
GROUP BY SalesAmount;
SELECT SalesAmount
FROM FactInternetSales
GROUP BY SalesAmount, SalesAmount * 1.10;

H. Использование предложения GROUP BY с несколькими выражениями GROUP BY

В следующем примере группируются результаты с помощью нескольких критериев GROUP BY. Если в каждой OrderDateKey группе подгруппы существуют, что DueDateKey значение отличается, запрос определяет новую группирование для результирующий набор.

-- Uses AdventureWorks
SELECT OrderDateKey,
       DueDateKey,
       SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey, DueDateKey
ORDER BY OrderDateKey;

I. Использование предложения GROUP BY с предложением HAVING

В следующем примере используется предложение HAVING, чтобы указать, какие группы, сформированные в предложении GROUP BY, должны быть включены в результирующий набор. В результаты включаются только группы с датами заказа в 2004 году или более поздней версии.

-- Uses AdventureWorks
SELECT OrderDateKey,
       SUM(SalesAmount) AS TotalSales
FROM FactInternetSales
GROUP BY OrderDateKey
HAVING OrderDateKey > 20040000
ORDER BY OrderDateKey;