In SQL, il GROUP BY
La clausola può essere utilizzata per dividere i risultati di una query in gruppi di righe.
Questo di solito viene fatto per eseguire una o più aggregazioni su ciascun gruppo.
Esempio 1
Ecco un esempio per dimostrare il GROUP BY
clausola.
Prendi la seguente tabella:
SELECT * FROM Products;
Risultato:
+-------------+------------+---------------------------------+----------------+-----------------------------------------+ | 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. | +-------------+------------+---------------------------------+----------------+-----------------------------------------+
Potremmo eseguire la seguente query su quella tabella.
SELECT
VendorId,
COUNT(VendorId) AS Count
FROM Products
GROUP BY VendorId;
Risultato:
+------------+---------+ | VendorId | Count | |------------+---------| | 1001 | 3 | | 1002 | 1 | | 1003 | 2 | | 1004 | 1 | +------------+---------+
Qui utilizziamo il COUNT()
funzione di aggregazione per restituire il numero di righe per ogni VendorId
, quindi il GROUP BY
clausola per raggruppare i risultati.
Esempio 2
In questo esempio utilizziamo il SUM()
funzione di aggregazione per restituire la popolazione aggregata di tutte le città all'interno di un distretto, quindi il GROUP BY
clausola per raggruppare i risultati.
Immagina di avere una tabella chiamata City
che memorizza i nomi delle città e la loro popolazione, nonché i rispettivi codici paese e distretti (in colonne separate).
In questo modo:
SELECT * FROM city
WHERE CountryCode IN ('AGO', 'ARE', 'AUS');
Risultato:
+------+---------------+---------------+-----------------+--------------+ | 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 | +------+---------------+---------------+-----------------+--------------+
Ho ridotto i risultati a soli tre paesi, altrimenti l'elenco sarebbe modo troppo lungo per questo articolo.
Supponiamo ora di voler ottenere la popolazione di ogni distretto e di voler elencare ogni distretto, insieme alla sua popolazione e al codice del paese.
Potremmo farlo.
SELECT
CountryCode,
District,
SUM(Population) AS Population
FROM City
WHERE CountryCode IN ('AGO', 'ARE', 'AUS')
GROUP BY CountryCode, District
ORDER BY CountryCode;
Risultato:
+---------------+-----------------+--------------+ | 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 | +---------------+-----------------+--------------+
Possiamo vedere che i nostri risultati sono raggruppati come specificato e ora otteniamo l'intera popolazione per ogni distretto (al contrario della popolazione delle singole città, che è così che sono archiviate nella tabella sottostante).
Nota che il GROUP BY
la clausola deve venire dopo qualsiasi WHERE
clausola e prima di qualsiasi ORDER BY
clausola.
Se volessimo ottenere la popolazione di ogni paese invece del distretto, la nostra domanda diventa ancora più compatta.
SELECT
CountryCode,
SUM(Population) AS Population
FROM City
WHERE CountryCode IN ('AGO', 'ARE', 'AUS')
GROUP BY CountryCode
ORDER BY CountryCode;
Risultato:
+---------------+--------------+ | CountryCode | Population | |---------------+--------------| | AGO | 2561600 | | ARE | 1728336 | | AUS | 11313666 | +---------------+--------------+
Tieni presente che questo particolare database di esempio è molto obsoleto e il numero della sua popolazione non riflette la realtà attuale.
Esempio 3 – La clausola HAVING
Puoi includere il HAVING
clausola con il tuo GROUP BY
clausola per filtrare i gruppi.
Esempio:
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;
Risultato:
+---------------+-----------------+--------------+ | CountryCode | District | Population | |---------------+-----------------+--------------| | AGO | Luanda | 2022000 | | AUS | New South Wales | 3993949 | | AUS | Queensland | 1805236 | | AUS | Victoria | 2990711 | | AUS | West Australia | 1096829 | +---------------+-----------------+--------------+
Il HAVING
la clausola è simile a WHERE
clausola, eccetto quella WHERE
filtra le singole righe, mentre HAVING
gruppi di filtri.
Inoltre, il WHERE
la clausola filtra i dati prima è raggruppato, mentre HAVING
filtra i dati dopo è raggruppato.
Il HAVING
La clausola accetta gli stessi operatori che puoi usare con WHERE
clausola (come =
, ) Operator for Beginners">>
, =) Operator for Beginners">>=
, IN
, LIKE
, ecc).