Partilhar via


SELECIONAR - AGRUPAR POR- Transact-SQL

Aplica-se a:SQL ServerBase de Dados SQL do AzureInstância Gerida do Azure SQLAzure Synapse AnalyticsSistema de Plataforma de Análise (PDW)Ponto de Extremidade de Análise SQL no Microsoft FabricArmazém no Microsoft FabricBase de Dados SQL no Microsoft Fabric

Uma cláusula de instrução SELECT que divide o resultado da consulta em grupos de linhas, geralmente executando uma ou mais agregações em cada grupo. A instrução SELECT retorna uma linha por grupo.

Syntax

Transact-SQL convenções de sintaxe

-- Syntax for SQL Server and Azure SQL Database   
-- 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 }    
       }

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

-- Syntax for Parallel Data Warehouse  
  
GROUP BY {
      column-name [ WITH (DISTRIBUTED_AGG) ]  
    | column-expression
} [ ,...n ]

Arguments

Expressão em coluna

Especifica uma coluna ou um cálculo não agregado em uma coluna. Esta coluna pode pertencer a uma tabela, tabela derivada ou vista. A coluna deve aparecer na cláusula FROM da instrução SELECT, mas não é necessária para aparecer na lista SELECT.

Para expressões válidas, consulte expressão.

A coluna deve aparecer na cláusula FROM da instrução SELECT, mas não é necessária para aparecer na lista SELECT. No entanto, cada tabela ou coluna de exibição em qualquer expressão não agregada <na lista de seleção> deve ser incluída na lista GROUP BY:

São permitidas as seguintes declarações:

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;  

Não são permitidas as seguintes declarações:

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

A expressão da coluna não pode conter:

  • Um alias de coluna definido na lista SELECT. Ele pode usar um alias de coluna para uma tabela derivada definida na cláusula FROM.
  • Uma coluna do tipo texto, ntext ou imagem. No entanto, você pode usar uma coluna de texto, ntext ou imagem como um argumento para uma função que retorna um valor de um tipo de dados válido. Por exemplo, a expressão pode usar SUBSTRING() e CAST(). O mesmo se aplica às expressões da cláusula HAVER.
  • Métodos de tipo de dados XML. Ele pode incluir uma função definida pelo usuário que usa métodos de tipo de dados xml. Ele pode incluir uma coluna computada que usa métodos de tipo de dados xml.
  • Uma subconsulta. O erro 144 é retornado.
  • Uma coluna de um modo de exibição indexado.

AGRUPAR POR coluna-expressão [ ,... n ]

Agrupa os resultados da instrução SELECT de acordo com os valores em uma lista de uma ou mais expressões de coluna.

Por exemplo, esta consulta cria uma tabela Sales com colunas para País, Região e Vendas. Ele insere quatro linhas e duas das linhas têm valores correspondentes para País e Região.

CREATE TABLE Sales ( Country VARCHAR(50), Region VARCHAR(50), Sales INT );

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);

A tabela Sales contém estas linhas:

Country Region Sales
Canada Alberta 100
Canada Colúmbia Britânica 200
Canada Colúmbia Britânica 300
Estados Unidos Montana 100

Esta próxima consulta agrupa País e Região e devolve a soma agregada para cada combinação de valores.

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

O resultado da consulta tem 3 linhas, pois existem 3 combinações de valores para País e Região. O TotalSales para Canadá e Colúmbia Britânica é a soma de duas linhas.

Country Region TotalSales
Canada Alberta 100
Canada Colúmbia Britânica 500
Estados Unidos Montana 100

GRUPO POR ROLLUP

Cria um grupo para cada combinação de expressões de coluna. Além disso, "enrola" os resultados em subtotais e totais gerais. Para fazer isso, ele se move da direita para a esquerda diminuindo o número de expressões de coluna sobre as quais cria grupos e agregação(ões).

A ordem das colunas afeta a saída ROLLUP e pode afetar o número de linhas no conjunto de resultados.

Por exemplo, GROUP BY ROLLUP (col1, col2, col3, col4) cria grupos para cada combinação de expressões de coluna nas listas a seguir.

  • Col1, Col2, Cole3, Col4
  • col1, col2, col3, NULL
  • col1, col2, NULL, NULL
  • COL1, NULO, NULO, NULO
  • NULL, NULL, NULL, NULL --Este é o total geral

Usando a tabela do exemplo anterior, esse código executa uma operação GROUP BY ROLLUP em vez de uma simples operação GROUP BY.

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

O resultado da consulta tem as mesmas agregações que o simples GROUP BY sem o ROLLUP. Além disso, cria subtotais para cada valor de País. Finalmente, dá um total geral para todas as linhas. O resultado é assim:

Country Region TotalSales
Canada Alberta 100
Canada Colúmbia Britânica 500
Canada NULL 600
Estados Unidos Montana 100
Estados Unidos NULL 100
NULL NULL 700

GRUPO POR CUBO ( )

GROUP BY CUBE cria grupos para todas as combinações possíveis de colunas. Para GROUP BY CUBE (a, b) os resultados têm grupos para valores exclusivos de (a, b), (NULL, b), (a, NULL) e (NULL, NULL).

Usando a tabela dos exemplos anteriores, esse código executa uma operação GROUP BY CUBE em País e Região.

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

O resultado da consulta tem grupos para valores exclusivos de (País, Região), (NULL, Região), (País, NULL) e (NULL, NULL). Os resultados são os seguintes:

Country Region TotalSales
Canada Alberta 100
NULL Alberta 100
Canada Colúmbia Britânica 500
NULL Colúmbia Britânica 500
Estados Unidos Montana 100
NULL Montana 100
NULL NULL 700
Canada NULL 600
Estados Unidos NULL 100

AGRUPAR POR AGRUPAR CONJUNTOS ( )

A opção GROUPING SETS oferece a capacidade de combinar várias cláusulas GROUP BY em uma cláusula GROUP BY. Os resultados são o equivalente a UNIÃO TODOS dos grupos especificados.

Por exemplo, GROUP BY ROLLUP (Country, Region) e GROUP BY GROUPING SETS ( ROLLUP (Country, Region) ) retornar os mesmos resultados.

Quando GROUPING SETS tem dois ou mais elementos, os resultados são uma união dos elementos. Este exemplo retorna a união dos resultados ROLLUP e CUBE para País e Região.

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

Os resultados são os mesmos que esta consulta que retorna uma união das duas instruções GROUP BY.

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

SQL não consolida grupos duplicados gerados para uma lista de conjuntos de agrupamento. Por exemplo, no GROUP BY ( (), CUBE (Country, Region) ), ambos os elementos retornam uma linha para o total geral e ambas as linhas serão listadas nos resultados.

GRUPO POR ()

Especifica o grupo vazio, que gera o total geral. Isso é útil como um dos elementos de um CONJUNTO DE AGRUPAMENTO. Por exemplo, esta declaração fornece o total de vendas para cada país/região e, em seguida, fornece o total geral para todos os países/regiões.

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

AGRUPAR POR TODOS coluna-expressão [ ,... n ]

Aplica-se a: SQL Server e Banco de Dados SQL do Azure

Note

Esta sintaxe é fornecida apenas para compatibilidade com versões anteriores. Ele será removido em uma versão futura. Evite usar essa sintaxe em novos trabalhos de desenvolvimento e planeje modificar aplicativos que atualmente usam essa sintaxe.

Especifica para incluir todos os grupos nos resultados, independentemente de atenderem aos critérios de pesquisa na cláusula WHERE. Os grupos que não atendem aos critérios de pesquisa têm NULL para a agregação.

GRUPO POR TODOS:

  • Não há suporte em consultas que acessam tabelas remotas se também houver uma cláusula WHERE na consulta.
  • Falhará em colunas que tenham o atributo FILESTREAM.

AGRUPAR POR coluna-expressão [ ,... n ] COM { CUBO | ROLLUP }

Aplica-se a: SQL Server e Banco de Dados SQL do Azure

Note

Esta sintaxe é fornecida apenas para compatibilidade com versões anteriores. Evite usar essa sintaxe em novos trabalhos de desenvolvimento e planeje modificar aplicativos que atualmente usam essa sintaxe.

COM (DISTRIBUTED_AGG)

Aplica-se a: Azure Synapse Analytics and Analytics Platform System (PDW)

A dica de consulta DISTRIBUTED_AGG força o sistema de processamento paralelo maciço (MPP) a redistribuir uma tabela em uma coluna específica antes de executar uma agregação. Apenas uma coluna na cláusula GROUP BY pode ter uma dica de consulta DISTRIBUTED_AGG. Após a conclusão da consulta, a tabela redistribuída é descartada. A tabela original não é alterada.

NOTA: A dica de consulta DISTRIBUTED_AGG é fornecida para compatibilidade com versões anteriores do Analytics Platform System (PDW) e não melhorará o desempenho da maioria das consultas. Por padrão, o MPP já redistribui dados conforme necessário para melhorar o desempenho de agregações.

Observações gerais

Como GROUP BY interage com a instrução SELECT

Lista SELECT:

  • Agregados vetoriais. Se as funções agregadas forem incluídas na lista SELECT, GROUP BY calculará um valor de resumo para cada grupo. Estes são conhecidos como agregados vetoriais.
  • Agregados distintos. Os agregados AVG (DISTINCT column_name), COUNT (DISTINCT column_name) e SUM (DISTINCT column_name) são suportados com ROLLUP, CUBE e GROUPING SETS.

cláusula WHERE:

  • O SQL remove Linhas que não atendem às condições da cláusula WHERE antes de qualquer operação de agrupamento ser executada.

cláusula HAVER:

  • SQL usa a cláusula having para filtrar grupos no conjunto de resultados.

CLÁUSULA DE ENCOMENDA POR:

  • Use a cláusula ORDER BY para ordenar o conjunto de resultados. A cláusula GROUP BY não ordena o conjunto de resultados.

Valores NULL:

  • Se uma coluna de agrupamento contiver valores NULL, todos os valores NULL serão considerados iguais e serão coletados em um único grupo.

Limitações e Restrições

Aplica-se a: SQL Server (a partir de 2008) e Azure Synapse Analytics

Capacidade máxima

Para uma cláusula GROUP BY que usa ROLLUP, CUBE ou GROUPING SETS, o número máximo de expressões é 32. O número máximo de grupos é de 4096 (212). Os exemplos a seguir falham porque a cláusula GROUP BY tem mais de 4096 grupos.

  • O exemplo a seguir gera 4097 (2,12 + 1) conjuntos de agrupamento e falhará.

    GROUP BY GROUPING SETS( CUBE(a1, ..., a12), b )  
    
  • O exemplo a seguir gera 4097 (2,12 + 1) grupos e falhará. Ambos e CUBE () o () conjunto de agrupamento produzem uma linha total geral e os conjuntos de agrupamento duplicados não são eliminados.

    GROUP BY GROUPING SETS( CUBE(a1, ..., a12), ())  
    
  • Este exemplo usa a sintaxe compatível com versões anteriores. Ele gera 8192 (213) conjuntos de agrupamento e falhará.

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

    Para cláusulas GROUP BY compatíveis com versões anteriores que não contêm CUBE ou ROLLUP, o número de grupos por itens é limitado pelos tamanhos das colunas GROUP BY, as colunas agregadas e os valores agregados envolvidos na consulta. Esse limite origina-se do limite de 8.060 bytes na tabela de trabalho intermediária necessária para armazenar resultados de consulta intermediários. Um máximo de 12 expressões de agrupamento é permitido quando CUBE ou ROLLUP é especificado.

Suporte para ISO e ANSI SQL-2006 GROUP BY Features

A cláusula GROUP BY suporta todos os recursos GROUP BY incluídos no padrão SQL-2006 com as seguintes exceções de sintaxe:

  • Os conjuntos de agrupamento não são permitidos na cláusula GROUP BY, a menos que façam parte de uma lista explícita de CONJUNTOS DE AGRUPAMENTO. Por exemplo, ) é permitido no padrão, GROUP BY Column1, (Column2, ...ColumnNmas não no Transact-SQL. Transact-SQL suportes GROUP BY C1, GROUPING SETS ((Column2, ...ColumnN)) e GROUP BY Column1, Column2, ... ColumnN, que são semanticamente equivalentes. Estes são semanticamente equivalentes ao exemplo anterior GROUP BY . Isso é para evitar a possibilidade de que GROUP BY Column1, (Column2, ...ColumnN) possa ser mal interpretado como GROUP BY C1, GROUPING SETS ((Column2, ...ColumnN)), que não são semanticamente equivalentes.

  • Conjuntos de agrupamento não são permitidos dentro de conjuntos de agrupamento. Por exemplo, é permitido no padrão SQL-2006, GROUP BY GROUPING SETS (A1, A2,...An, GROUPING SETS (C1, C2, ...Cn)) mas não no Transact-SQL. Transact-SQL permite GROUP BY GROUPING SETS( A1, A2,...An, C1, C2, ...Cn ) ou GROUP BY GROUPING SETS( (A1), (A2), ... (An), (C1), (C2), ... (Cn) ), que são semanticamente equivalentes ao primeiro exemplo GROUP BY e têm uma sintaxe mais clara.

  • GROUP BY [ALL/DISTINCT] só é permitido em uma cláusula simples GROUP BY que contenha expressões de coluna. Não é permitido com as construções GROUPING SETS, ROLLUP, CUBE, WITH CUBE ou WITH ROLLUP. ALL é o padrão e está implícito. Também só é permitido na sintaxe compatível com versões anteriores.

Comparação dos recursos GROUP BY suportados

A tabela a seguir descreve os recursos GROUP BY suportados com base nas versões SQL e no nível de compatibilidade do banco de dados.

Feature SQL Server Integration Services Nível de compatibilidade do SQL Server 100 ou superior SQL Server 2008 ou posterior com nível de compatibilidade 90.
Agregados DISTINTOS Não suportado para WITH CUBE ou WITH ROLLUP. Compatível com WITH CUBE, WITH ROLLUP, GROUPING SETS, CUBE ou ROLLUP. O mesmo que o nível de compatibilidade 100.
Função definida pelo usuário com nome CUBE ou ROLLUP na cláusula GROUP BY Função definida pelo usuário dbo.cube(arg1,... argN) ou dbo.rollup(arg1,... argN) na cláusula GROUP BY é permitido.

Por exemplo: SELECT SUM (x) FROM T GROUP BY dbo.cube(y);
Função definida pelo usuário dbo.cube (arg1,... argN**)** ou dbo.rollup(arg1,... argN) na cláusula GROUP BY não é permitido.

Por exemplo: SELECT SUM (x) FROM T GROUP BY dbo.cube(y);

A seguinte mensagem de erro é retornada: "Sintaxe incorreta perto da palavra-chave 'cube'|' rollup'."

Para evitar esse problema, substitua dbo.cube por [dbo].[cube] ou dbo.rollup por [dbo].[rollup].

O seguinte exemplo é permitido: SELECT SUM (x) FROM T GROUP BY [dbo].[cube](y);
Função definida pelo usuário dbo.cube (arg1,... argN) ou dbo.rollup(arg1,... argN) na cláusula GROUP BY é permitida

Por exemplo: SELECT SUM (x) FROM T GROUP BY dbo.cube(y);
CONJUNTOS DE AGRUPAMENTO Não suportado Supported Supported
CUBE Não suportado Supported Não suportado
ROLLUP Não suportado Supported Não suportado
Total geral, como GROUP BY () Não suportado Supported Supported
GROUPING_ID função Não suportado Supported Supported
Função de AGRUPAMENTO Supported Supported Supported
COM CUBE Supported Supported Supported
COM ROLLUP Supported Supported Supported
COM CUBE ou COM ROLLUP remoção de agrupamento "duplicado" Supported Supported Supported

Examples

A. Use uma cláusula simples GROUP BY

O exemplo a seguir recupera o total de cada SalesOrderID um da SalesOrderDetail tabela. Este exemplo usa AdventureWorks.

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

B. Usar uma cláusula GROUP BY com várias tabelas

O exemplo a seguir recupera o número de funcionários de cada City um da Address tabela unida à EmployeeAddress tabela. Este exemplo usa AdventureWorks.

SELECT a.City, COUNT(bea.AddressID) 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. Usar uma cláusula GROUP BY com uma expressão

O exemplo a seguir recupera o total de vendas de cada ano usando a DATEPART função. A mesma expressão deve estar presente tanto na SELECT lista GROUP BY como na cláusula.

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. Use uma cláusula GROUP BY com uma cláusula HAVING

O exemplo a seguir usa a HAVING cláusula para especificar quais dos grupos gerados na GROUP BY cláusula devem ser incluídos no conjunto de resultados.

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);  

Exemplos: Azure Synapse Analytics e Parallel Data Warehouse

E. Utilização básica da cláusula GROUP BY

O exemplo a seguir localiza o valor total de todas as vendas em cada dia. Uma linha contendo a soma de todas as vendas é devolvida para cada dia.

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

F. Uso básico da dica DISTRIBUTED_AGG

Este exemplo usa a dica de consulta DISTRIBUTED_AGG para forçar o dispositivo a embaralhar a CustomerKey tabela na coluna antes de executar a agregação.

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

G. Variações de sintaxe para GROUP BY

Quando a lista de seleção não tem agregações, cada coluna na lista de seleção deve ser incluída na lista GRUPO POR. As colunas computadas na lista de seleção podem ser listadas, mas não são obrigatórias, na lista AGRUPAR POR. Estes são exemplos de instruções SELECT sintaticamente válidas:

-- 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 SalesTax FROM FactInternetSales GROUP BY SalesAmount;  
SELECT SalesAmount FROM FactInternetSales GROUP BY SalesAmount, SalesAmount*1.10;  

H. Usando um GROUP BY com várias expressões GROUP BY

O exemplo a seguir agrupa resultados usando vários GROUP BY critérios. Se, dentro de cada OrderDateKey grupo, houver subgrupos que possam ser diferenciados por DueDateKey, um novo agrupamento será definido para o conjunto de resultados.

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

I. Usando uma cláusula GROUP BY com uma cláusula HAVING

O exemplo a seguir usa a HAVING cláusula para especificar os grupos gerados na GROUP BY cláusula que devem ser incluídos no conjunto de resultados. Apenas os grupos com datas de encomenda em 2004 ou posteriores serão incluídos nos resultados.

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

Ver também

GROUPING_ID (Transact-SQL)
AGRUPAMENTO (Transact-SQL)
SELECIONAR (Transact-SQL)
Cláusula SELECT (Transact-SQL)