I SQL, GROUP BY
sats kan användas för att dela upp resultaten av en fråga i grupper av rader.
Detta görs vanligtvis för att utföra en eller flera aggregationer på varje grupp.
Exempel 1
Här är ett exempel för att demonstrera GROUP BY
klausul.
Ta följande tabell:
SELECT * FROM Products;
Resultat:
+-------------+------------+---------------------------------+----------------+-----------------------------------------+ | 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. | +-------------+------------+---------------------------------+----------------+-----------------------------------------+
Vi kan köra följande fråga mot den tabellen.
SELECT
VendorId,
COUNT(VendorId) AS Count
FROM Products
GROUP BY VendorId;
Resultat:
+------------+---------+ | VendorId | Count | |------------+---------| | 1001 | 3 | | 1002 | 1 | | 1003 | 2 | | 1004 | 1 | +------------+---------+
Här använder vi COUNT()
aggregatfunktion för att returnera antalet rader för varje VendorId
, sedan GROUP BY
klausul för att gruppera resultaten.
Exempel 2
I det här exemplet använder vi SUM()
aggregatfunktion för att returnera den aggregerade befolkningen för alla städer inom ett distrikt, sedan GROUP BY
klausul för att gruppera resultaten.
Föreställ dig att vi har en tabell som heter City
som lagrar stadsnamn och deras befolkning, såväl som deras respektive landskoder och distrikt (i sina egna separata kolumner).
Så här:
SELECT * FROM city
WHERE CountryCode IN ('AGO', 'ARE', 'AUS');
Resultat:
+------+---------------+---------------+-----------------+--------------+ | 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 | +------+---------------+---------------+-----------------+--------------+
Jag minskade resultaten till bara tre länder, annars skulle listan vara väg för lång för den här artikeln.
Anta nu att vi ville få befolkningen i varje distrikt, och vi ville lista varje distrikt, tillsammans med dess befolkning och landskod.
Vi skulle kunna göra det här.
SELECT
CountryCode,
District,
SUM(Population) AS Population
FROM City
WHERE CountryCode IN ('AGO', 'ARE', 'AUS')
GROUP BY CountryCode, District
ORDER BY CountryCode;
Resultat:
+---------------+-----------------+--------------+ | 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 | +---------------+-----------------+--------------+
Vi kan se att våra resultat är grupperade enligt specifikation, och vi får nu hela befolkningen för varje distrikt (till skillnad från befolkningen i de enskilda städerna, vilket är hur de lagras i den underliggande tabellen).
Observera att GROUP BY
klausul måste komma efter någon WHERE
klausul och före någon ORDER BY
klausul.
Om vi ville få befolkningen i varje land istället för distriktet, blir vår fråga ännu mer kompakt.
SELECT
CountryCode,
SUM(Population) AS Population
FROM City
WHERE CountryCode IN ('AGO', 'ARE', 'AUS')
GROUP BY CountryCode
ORDER BY CountryCode;
Resultat:
+---------------+--------------+ | CountryCode | Population | |---------------+--------------| | AGO | 2561600 | | ARE | 1728336 | | AUS | 11313666 | +---------------+--------------+
Tänk på att just denna exempeldatabas är mycket föråldrad och att dess befolkningstal inte speglar den nuvarande verkligheten.
Exempel 3 – HAVING-klausulen
Du kan inkludera koden HAVING
sats med din GROUP BY
klausul för att filtrera grupperna.
Exempel:
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;
Resultat:
+---------------+-----------------+--------------+ | CountryCode | District | Population | |---------------+-----------------+--------------| | AGO | Luanda | 2022000 | | AUS | New South Wales | 3993949 | | AUS | Queensland | 1805236 | | AUS | Victoria | 2990711 | | AUS | West Australia | 1096829 | +---------------+-----------------+--------------+
HAVING
satsen liknar WHERE
sats, förutom att WHERE
filtrerar enskilda rader, medan HAVING
filtrerar grupper.
Även WHERE
klausul filtrerar data före den är grupperad, medan HAVING
filtrerar data efter den är grupperad.
HAVING
satsen accepterar samma operatorer som du kan använda med WHERE
klausul (som =
, ) Operator for Beginners">>
, =) Operator for Beginners">>=
, IN
, LIKE
osv.).