No SQL, o
GROUP BY
cláusula pode ser usada para dividir os resultados de uma consulta em grupos de linhas. Isso geralmente é feito para realizar uma ou mais agregações em cada grupo.
Exemplo 1
Aqui está um exemplo para demonstrar o
GROUP BY
cláusula. Pegue a seguinte tabela:
SELECT * FROM Products;
Resultado:
+-------------+------------+---------------------------------+----------------+-----------------------------------------+ | ProductId | VendorId | ProductName | ProductPrice | ProductDescription | |-------------+------------+---------------------------------+----------------+-----------------------------------------| | 1 | 1001 | Left handed screwdriver | 25.99 | Purple. Includes left handed carry box. | | 2 | 1001 | Long Weight (blue) | 14.75 | Includes a long wait. | | 3 | 1001 | Long Weight (green) | 11.99 | Approximate 30 minute waiting period. | | 4 | 1002 | Sledge Hammer | 33.49 | Wooden handle. Free wine glasses. | | 5 | 1003 | Chainsaw | 245.00 | Orange. Includes spare fingers. | | 6 | 1003 | Straw Dog Box | 55.99 | Tied with vines. Very chewable. | | 7 | 1004 | Bottomless Coffee Mugs (4 Pack) | 9.99 | Brown ceramic with solid handle. | +-------------+------------+---------------------------------+----------------+-----------------------------------------+
Poderíamos executar a seguinte consulta nessa tabela.
SELECT
VendorId,
COUNT(VendorId) AS Count
FROM Products
GROUP BY VendorId;
Resultado:
+------------+---------+ | VendorId | Count | |------------+---------| | 1001 | 3 | | 1002 | 1 | | 1003 | 2 | | 1004 | 1 | +------------+---------+
Aqui, usamos o
COUNT()
função agregada para retornar o número de linhas para cada VendorId
, então o GROUP BY
cláusula para agrupar os resultados. Exemplo 2
Neste exemplo, usamos o
SUM()
função agregada para retornar a população agregada de todas as cidades dentro de um distrito, então o GROUP BY
cláusula para agrupar os resultados. Imagine que temos uma tabela chamada
City
que armazena nomes de cidades e sua população, bem como seus respectivos códigos de país e distritos (em suas próprias colunas separadas). Assim:
SELECT * FROM city
WHERE CountryCode IN ('AGO', 'ARE', 'AUS');
Resultado:
+------+---------------+---------------+-----------------+--------------+ | ID | Name | CountryCode | District | Population | |------+---------------+---------------+-----------------+--------------| | 56 | Luanda | AGO | Luanda | 2022000 | | 57 | Huambo | AGO | Huambo | 163100 | | 58 | Lobito | AGO | Benguela | 130000 | | 59 | Benguela | AGO | Benguela | 128300 | | 60 | Namibe | AGO | Namibe | 118200 | | 64 | Dubai | ARE | Dubai | 669181 | | 65 | Abu Dhabi | ARE | Abu Dhabi | 398695 | | 66 | Sharja | ARE | Sharja | 320095 | | 67 | al-Ayn | ARE | Abu Dhabi | 225970 | | 68 | Ajman | ARE | Ajman | 114395 | | 130 | Sydney | AUS | New South Wales | 3276207 | | 131 | Melbourne | AUS | Victoria | 2865329 | | 132 | Brisbane | AUS | Queensland | 1291117 | | 133 | Perth | AUS | West Australia | 1096829 | | 134 | Adelaide | AUS | South Australia | 978100 | | 135 | Canberra | AUS | Capital Region | 322723 | | 136 | Gold Coast | AUS | Queensland | 311932 | | 137 | Newcastle | AUS | New South Wales | 270324 | | 138 | Central Coast | AUS | New South Wales | 227657 | | 139 | Wollongong | AUS | New South Wales | 219761 | | 140 | Hobart | AUS | Tasmania | 126118 | | 141 | Geelong | AUS | Victoria | 125382 | | 142 | Townsville | AUS | Queensland | 109914 | | 143 | Cairns | AUS | Queensland | 92273 | +------+---------------+---------------+-----------------+--------------+
Reduzi os resultados para apenas três países, caso contrário a lista seria maneira muito longo para este artigo.
Agora, suponha que queremos obter a população de cada distrito e listar cada distrito, juntamente com sua população e código do país.
Nós poderíamos fazer isso.
SELECT
CountryCode,
District,
SUM(Population) AS Population
FROM City
WHERE CountryCode IN ('AGO', 'ARE', 'AUS')
GROUP BY CountryCode, District
ORDER BY CountryCode;
Resultado:
+---------------+-----------------+--------------+ | CountryCode | District | Population | |---------------+-----------------+--------------| | AGO | Benguela | 258300 | | AGO | Huambo | 163100 | | AGO | Luanda | 2022000 | | AGO | Namibe | 118200 | | ARE | Abu Dhabi | 624665 | | ARE | Ajman | 114395 | | ARE | Dubai | 669181 | | ARE | Sharja | 320095 | | AUS | Capital Region | 322723 | | AUS | New South Wales | 3993949 | | AUS | Queensland | 1805236 | | AUS | South Australia | 978100 | | AUS | Tasmania | 126118 | | AUS | Victoria | 2990711 | | AUS | West Australia | 1096829 | +---------------+-----------------+--------------+
Podemos ver que nossos resultados estão agrupados conforme especificado e agora obtemos a população total de cada distrito (em oposição à população das cidades individuais, que é como elas são armazenadas na tabela subjacente).
Observe que o
GROUP BY
cláusula deve vir após qualquer WHERE
cláusula e antes de qualquer ORDER BY
cláusula. Se quisermos obter a população de cada país em vez do distrito, nossa consulta se torna ainda mais compacta.
SELECT
CountryCode,
SUM(Population) AS Population
FROM City
WHERE CountryCode IN ('AGO', 'ARE', 'AUS')
GROUP BY CountryCode
ORDER BY CountryCode;
Resultado:
+---------------+--------------+ | CountryCode | Population | |---------------+--------------| | AGO | 2561600 | | ARE | 1728336 | | AUS | 11313666 | +---------------+--------------+
Lembre-se de que esse banco de dados de amostra específico está muito desatualizado e seus números populacionais não refletem a realidade atual.
Exemplo 3 - A Cláusula HAVING
Você pode incluir o
HAVING
cláusula com seu GROUP BY
cláusula para filtrar os grupos. Exemplo:
SELECT
CountryCode,
District,
SUM(Population) AS Population
FROM City
WHERE CountryCode IN ('AGO', 'ARE', 'AUS')
GROUP BY CountryCode, District
HAVING SUM(Population) > 1000000
ORDER BY CountryCode;
Resultado:
+---------------+-----------------+--------------+ | CountryCode | District | Population | |---------------+-----------------+--------------| | AGO | Luanda | 2022000 | | AUS | New South Wales | 3993949 | | AUS | Queensland | 1805236 | | AUS | Victoria | 2990711 | | AUS | West Australia | 1096829 | +---------------+-----------------+--------------+
O
HAVING
cláusula é semelhante à WHERE
cláusula, exceto que WHERE
filtra linhas individuais, enquanto HAVING
grupos de filtros. Além disso, o
WHERE
cláusula filtra dados antes é agrupado, enquanto HAVING
filtra dados depois ele é agrupado. O
HAVING
cláusula aceita os mesmos operadores que você pode usar com o WHERE
cláusula (como =
, ) Operator for Beginners">>
, =) Operator for Beginners">>=
, IN
, LIKE
, etc).