Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Synapse SQL permite o desenvolvimento de soluções através da implementação de diferentes opções GROUP BY.
O que faz o GROUP BY
A cláusula GROUP BY T-SQL agrega dados a um conjunto resumido de linhas.
O pool SQL sem servidor não oferece suporte às opções GROUP BY. O pool SQL dedicado oferece suporte a um número limitado de opções GROUP BY.
Opções GROUP BY suportadas no pool SQL dedicado
GROUP BY tem algumas opções que o pool SQL dedicado não suporta. Essas opções têm soluções alternativas, que são as seguintes:
- AGRUPAR POR com ROLLUP
- CONJUNTOS DE AGRUPAMENTO
- GROUP BY com CUBE
Opções de conjuntos de rollup e agrupamento
A opção mais simples aqui é usar UNION ALL para executar o rollup em vez de confiar na sintaxe explícita. O resultado é exatamente o mesmo
O exemplo a seguir usa a instrução GROUP BY com a opção ROLLUP:
SELECT [SalesTerritoryCountry]
, [SalesTerritoryRegion]
, SUM(SalesAmount) AS TotalSalesAmount
FROM dbo.factInternetSales s
JOIN dbo.DimSalesTerritory t ON s.SalesTerritoryKey = t.SalesTerritoryKey
GROUP BY ROLLUP (
[SalesTerritoryCountry]
, [SalesTerritoryRegion]
)
;
Usando ROLLUP, o exemplo anterior solicita as seguintes agregações:
- País e Região
- País
- Total geral
Para substituir ROLLUP e retornar os mesmos resultados, você pode usar UNION ALL e especificar explicitamente as agregações necessárias:
SELECT [SalesTerritoryCountry]
, [SalesTerritoryRegion]
, SUM(SalesAmount) AS TotalSalesAmount
FROM dbo.factInternetSales s
JOIN dbo.DimSalesTerritory t ON s.SalesTerritoryKey = t.SalesTerritoryKey
GROUP BY
[SalesTerritoryCountry]
, [SalesTerritoryRegion]
UNION ALL
SELECT [SalesTerritoryCountry]
, NULL
, SUM(SalesAmount) AS TotalSalesAmount
FROM dbo.factInternetSales s
JOIN dbo.DimSalesTerritory t ON s.SalesTerritoryKey = t.SalesTerritoryKey
GROUP BY
[SalesTerritoryCountry]
UNION ALL
SELECT NULL
, NULL
, SUM(SalesAmount) AS TotalSalesAmount
FROM dbo.factInternetSales s
JOIN dbo.DimSalesTerritory t ON s.SalesTerritoryKey = t.SalesTerritoryKey;
Para substituir os CONJUNTOS DE AGRUPAMENTO, aplica-se o princípio de amostragem. Você só precisa criar seções UNION ALL para os níveis de agregação que deseja ver.
Opções de cubo
É possível criar um GROUP BY WITH CUBE usando a abordagem UNION ALL. O problema é que o código pode rapidamente se tornar vexatório e complicado. Para atenuar esse problema, você pode usar essa abordagem mais avançada.
O primeiro passo é definir o 'cubo' que define todos os níveis de agregação que queremos criar. Tome nota da JUNÇÃO CRUZADA das duas tabelas derivadas, pois gera todos os níveis. O resto do código está lá para formatação.
CREATE TABLE #Cube
WITH
( DISTRIBUTION = ROUND_ROBIN
, LOCATION = USER_DB
)
AS
WITH GrpCube AS
(SELECT CAST(ISNULL(Country,'NULL')+','+ISNULL(Region,'NULL') AS NVARCHAR(50)) as 'Cols'
, CAST(ISNULL(Country+',','')+ISNULL(Region,'') AS NVARCHAR(50)) as 'GroupBy'
, ROW_NUMBER() OVER (ORDER BY Country) as 'Seq'
FROM ( SELECT 'SalesTerritoryCountry' as Country
UNION ALL
SELECT NULL
) c
CROSS JOIN ( SELECT 'SalesTerritoryRegion' as Region
UNION ALL
SELECT NULL
) r
)
SELECT Cols
, CASE WHEN SUBSTRING(GroupBy,LEN(GroupBy),1) = ','
THEN SUBSTRING(GroupBy,1,LEN(GroupBy)-1)
ELSE GroupBy
END AS GroupBy --Remove Trailing Comma
,Seq
FROM GrpCube;
A imagem a seguir mostra os resultados de CREATE TABLE AS SELECT:
A segunda etapa é especificar uma tabela de destino para armazenar resultados provisórios:
DECLARE
@SQL NVARCHAR(4000)
,@Columns NVARCHAR(4000)
,@GroupBy NVARCHAR(4000)
,@i INT = 1
,@nbr INT = 0
;
CREATE TABLE #Results
(
[SalesTerritoryCountry] NVARCHAR(50)
,[SalesTerritoryRegion] NVARCHAR(50)
,[TotalSalesAmount] MONEY
)
WITH
( DISTRIBUTION = ROUND_ROBIN
, LOCATION = USER_DB
)
;
O terceiro passo é executar um loop sobre o cubo de colunas para realizar a agregação. A consulta será executada uma vez para cada linha na tabela temporária #Cube. Os resultados são armazenados na tabela temporária #Results:
SET @nbr =(SELECT MAX(Seq) FROM #Cube);
WHILE @i<=@nbr
BEGIN
SET @Columns = (SELECT Cols FROM #Cube where seq = @i);
SET @GroupBy = (SELECT GroupBy FROM #Cube where seq = @i);
SET @SQL ='INSERT INTO #Results
SELECT '+@Columns+'
, SUM(SalesAmount) AS TotalSalesAmount
FROM dbo.factInternetSales s
JOIN dbo.DimSalesTerritory t
ON s.SalesTerritoryKey = t.SalesTerritoryKey
'+CASE WHEN @GroupBy <>''
THEN 'GROUP BY '+@GroupBy ELSE '' END
EXEC sp_executesql @SQL;
SET @i +=1;
END
Por fim, você pode retornar os resultados lendo a tabela #Results temporária:
SELECT *
FROM #Results
ORDER BY 1,2,3
;
Ao dividir o código em seções e gerar uma construção de looping, o código se torna mais gerenciável e sustentável.
Próximos passos
Para obter mais dicas de desenvolvimento, consulte Visão geral do desenvolvimento.