21st Jul 2022 6 minutos de leitura Qual é a cláusula do SQL GROUPING SETS, e como você a utiliza? Andrew Bone sql aprender sql group by ORDER BY Índice Sintaxe dos conjuntos de agrupamentos SQL Exemplo de conjuntos de SQL GROUPING SETS Exemplo SQL ROLLUP Exemplo de CUBE SQL Agrupe seus dados de forma eficaz com o SQL GROUP BY Extensions Os GROUPING SETS são grupos, ou conjuntos, de colunas pelas quais as linhas podem ser agrupadas. Em vez de escrever várias consultas e combinar os resultados com um UNION, você pode simplesmente usar GROUPING SETS. GROUPING SETS em SQL pode ser considerado uma extensão da cláusula GROUP BY. Ela permite que você defina múltiplos conjuntos de agrupamento na mesma consulta. Vejamos sua sintaxe e como ela pode ser equivalente a uma GROUP BY com múltiplas cláusulas UNION ALL. Sintaxe dos conjuntos de agrupamentos SQL A sintaxe geral do GROUPING SETS é a seguinte: SELECT aggregate_function(column_1) column_2, column_3, FROM table_name GROUP BY GROUPING SETS ( (column_2, column_3), (column_2), (column_3), () ); Você pode ver como estamos nos agrupando pelos diferentes conjuntos. Esta sintaxe é equivalente à seguinte consulta mais longa que usa GROUP BY com UNION ALL para combinar os resultados: SELECT SUM(column_1), column_2, column_3 FROM table_name GROUP BY column_2, column_3 UNION ALL SELECT SUM(column_1), column_2, NULL FROM table_name GROUP BY column_2 UNION ALL SELECT SUM(column_1), NULL, column_3 FROM table_name GROUP BY column_3 UNION ALL SELECT SUM(column_1), NULL, NULL FROM table_name Se você usar o GROUP BY assim, você precisa de várias cláusulas UNION ALL para combinar os dados de diferentes fontes. UNION ALL também exige que todos os conjuntos de resultados tenham o mesmo número de colunas com tipos de dados compatíveis, portanto você precisa ajustar as consultas adicionando um valor NULL quando necessário. Mesmo que a consulta funcione como você espera, ela tem dois problemas principais: Ela é longa e pouco administrável. Ela pode levar a um problema de desempenho, pois o SQL tem que escanear a tabela de vendas a cada vez. A cláusula GROUPING SETS aborda estes problemas. Mas como ela afeta a saída em comparação com uma cláusula GROUP BY tradicional? É hora de olhar para um exemplo! Exemplo de conjuntos de SQL GROUPING SETS Precisamos de alguns exemplos de dados. Vamos criar uma tabela chamada payments que contém todos os pagamentos que nossa empresa recebeu em janeiro, fevereiro e março dos últimos quatro anos, de 2018 a 2021. A loja exata onde ocorreu o pagamento é assinalada pela coluna store_id. Para criar esta tabela, execute a seguinte consulta: CREATE TABLE payment (payment_amount decimal(8,2), payment_date date, store_id int); INSERT INTO payment VALUES (1200.99, '2018-01-18', 1), (189.23, '2018-02-15', 1), (33.43, '2018-03-03', 3), (7382.10, '2019-01-11', 2), (382.92, '2019-02-18', 1), (322.34, '2019-03-29', 2), (2929.14, '2020-01-03', 2), (499.02, '2020-02-19', 3), (994.11, '2020-03-14', 1), (394.93, '2021-01-22', 2), (3332.23, '2021-02-23', 3), (9499.49, '2021-03-10', 3), (3002.43, '2018-02-25', 2), (100.99, '2019-03-07', 1), (211.65, '2020-02-02', 1), (500.73, '2021-01-06', 3); Você pode visualizar os dados usando esta simples cláusula SELECT: SELECT * FROM payment ORDER BY payment_date; A execução desta consulta produz o resultado: payment_amountpayment_datestore_id 1200.992018-01-181 189.232018-02-151 3002.432018-02-252 33.432018-03-033 7382.102019-01-112 382.922019-02-181 100.992019-03-071 322.342019-03-292 2929.142020-01-032 211.652020-02-021 499.022020-02-193 994.112020-03-141 500.732021-01-063 394.932021-01-222 3332.232021-02-233 9499.492021-03-103 Você pode ver que existem múltiplas entradas para algumas lojas. Imagine que estamos preparando um relatório e queremos ver um total para cada loja. A função agregada SUM() pode nos ajudar com isto. Também usaremos a cláusula GROUP BY para agrupar nossos resultados por ano e loja. SELECT SUM(payment_amount), YEAR(payment_date) AS 'Payment Year', store_id AS 'Store' FROM payment GROUP BY YEAR(payment_date), store_id ORDER BY YEAR(payment_date), store_id; SUM(payment_amount)Payment YearStore 1390.2220181 3002.4320182 33.4320183 483.9120191 7704.4420192 1205.7620201 2929.1420202 499.0220203 394.9320212 13332.4520213 Os resultados são agregados por cada combinação única de ano e loja. Entretanto, não podemos ver o total de pagamentos por ano: o total de pagamentos para 2018, 2019, 2020, ou 2021. Também não podemos ver os totais por loja, o que seria uma métrica útil de se ter. O uso de GROUPING SETS nos permite ver estes totais. SELECT SUM(payment_amount), YEAR(payment_date) AS 'Payment Year', store_id AS 'Store' FROM payment_new GROUP BY GROUPING SETS (YEAR(payment_date), store_id) ORDER BY YEAR(payment_date), store_id; SUM(payment_amount)Payment YearStore 3079.89NULL1 14030.94NULL2 13864.90NULL3 4426.082018NULL 8188.352019NULL 4633.922020NULL 13727.382021NULL Uau, nossos resultados mudaram drasticamente! Agora, vemos apenas os totais totais gerais de cada loja junto com os totais gerais de cada ano. Para as colunas pelas quais as filas não estão agrupadas, você vê os valores NULL. Lembre-se que você pode incluir múltiplas cláusulas GROUP BY em seu GROUPING SETS. Aplicando isto à nossa consulta, obtemos os seguintes resultados: SELECT SUM(payment_amount), YEAR(payment_date) AS 'Payment Year', store_id AS 'Store' FROM payment_new GROUP BY GROUPING SETS ( (YEAR(payment_date), store_id), (YEAR(payment_date)), (store_id) ) ORDER BY YEAR(payment_date), store_id; SUM(payment_amount)Payment YearStore 3079.89NULL1 14030.94NULL2 13864.90NULL3 4426.082018NULL 1390.2220181 3002.4320182 33.4320183 8188.352019NULL 483.9120191 7704.4420192 4633.922020NULL 1205.7620201 2929.1420202 499.0220203 13727.382021NULL 394.9320212 13332.4520213 Antes de terminar este tutorial, devemos mencionar duas outras extensões do SQL GROUP BY que podem ser úteis para seu projeto ou cenário em particular: ROLLUP e CUBE. Estes tópicos são abordados em grande detalhe neste SQL Avançado learning track de LearnSQL.com.br que apresenta funções de janela, GROUP BY extensões, e consultas recursivas. Exemplo SQL ROLLUP Similar a GROUPING SETS, você pode usar a opção ROLLUP em uma única consulta para gerar vários conjuntos de agrupamentos. ROLLUP assume uma hierarquia entre as colunas de entrada. Por exemplo, se as colunas de entrada forem: GROUP BY ROLLUP(column_1,column_2) a hierarquia para isso é column_1 > column_2, e ROLLUP gera os seguintes conjuntos de agrupamentos: (column_1, column_2) (column_1) () ROLLUP gera todos os conjuntos de agrupamento que fazem sentido nesta hierarquia. Ele gera uma linha subtotal toda vez que o valor de column_1 muda; esta é a hierarquia que fornecemos. Por esta razão, muitas vezes usamos ROLLUP para gerar subtotais e grandes totais em relatórios. A ordenação de suas colunas em ROLLUP é muito importante. Vejamos uma consulta que usa ROLLUP: SELECT SUM(payment_amount), YEAR(payment_date) AS 'Payment Year', store_id AS 'Store' FROM payment GROUP BY ROLLUP (YEAR(payment_date), store_id) ORDER BY YEAR(payment_date), store_id SUM(payment_amount)Payment YearStore 30975.73NULLNULL 4426.082018NULL 1390.2220181 3002.4320182 33.4320183 8188.352019NULL 483.9120191 7704.4420192 4633.922020NULL 1205.7620201 2929.1420202 499.0220203 13727.382021NULL 394.9320212 13332.4520213 O total geral é mostrado na parte superior do resultado: 30975.73NULLNULL O resto do resultado é estruturado da seguinte forma. Primeiro, o total anual é mostrado: 4426.082018NULL Em seguida, os totais por loja por ano: 1390.2220181 3002.4320182 33.4320183 Como você pode ver, ROLLUP gera uma linha subtotal toda vez que o valor de Payment Year muda, já que esta é a hierarquia que fornecemos. Este exemplo mostra como ROLLUP pode ser útil para fins de relatórios. Exemplo de CUBE SQL Similar a ROLLUP, CUBE é uma extensão da cláusula GROUP BY. Ela permite gerar subtotais para todas as combinações das colunas de agrupamento especificadas na cláusula GROUP BY. O CUBE é como combinar GROUPING SETS e ROLLUP. Ele mostra a saída detalhada de ambos. SELECT SUM(payment_amount), YEAR(payment_date) AS 'Payment Year', store_id AS 'Store' FROM payment GROUP BY CUBE (YEAR(payment_date), store_id) ORDER BY YEAR(payment_date), store_id SUM(payment_amount)Payment YearStore 30975.73NULLNULL 3079.89NULL1 14030.94NULL2 13864.90NULL3 4426.082018NULL 1390.2220181 3002.4320182 33.4320183 8188.352019NULL 483.9120191 7704.4420192 4633.922020NULL 1205.7620201 2929.1420202 499.0220203 13727.382021NULL 394.9320212 13332.4520213 A principal diferença nesta saída do exemplo ROLLUP é que o total geral para cada loja também é mostrado aqui. 3079.89NULL1 14030.94NULL2 13864.90NULL3 Além destas linhas, todas as linhas neste resultado são as mesmas que o resultado do ROLLUP. Isto conclui nossa comparação de GROUPING SETS, ROLLUP, e CUBE! Você pode encontrar mais exemplos neste artigo sobre agrupamento, rolagem e cubagem de dados. Agrupe seus dados de forma eficaz com o SQL GROUP BY Extensions O domínio das extensões SQL GROUP BY será praticado. Opções como GROUPING SETS, ROLLUP, e CUBE permitem manipular os resultados de suas consultas de diferentes maneiras. Saber como usar essas extensões reduz efetivamente a necessidade de formatar manualmente seus dados antes de repassá-los aos interessados relevantes. Para expandir ainda mais seus conhecimentos nesta área, considere este curso de extensão GROUP BY de LearnSQL.com.br que abrange GROUPING SETS, ROLLUP, e CUBE. Tags: sql aprender sql group by ORDER BY