V SQL, GROUP BY
klauzuli lze použít k rozdělení výsledků dotazu do skupin řádků.
To se obvykle provádí za účelem provedení jedné nebo více agregací v každé skupině.
Příklad 1
Zde je příklad demonstrující GROUP BY
doložka.
Vezměte si následující tabulku:
SELECT * FROM Products;
Výsledek:
+-------------+------------+---------------------------------+----------------+-----------------------------------------+ | 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. | +-------------+------------+---------------------------------+----------------+-----------------------------------------+
Proti této tabulce bychom mohli spustit následující dotaz.
SELECT
VendorId,
COUNT(VendorId) AS Count
FROM Products
GROUP BY VendorId;
Výsledek:
+------------+---------+ | VendorId | Count | |------------+---------| | 1001 | 3 | | 1002 | 1 | | 1003 | 2 | | 1004 | 1 | +------------+---------+
Zde používáme COUNT()
agregační funkce, která vrátí počet řádků pro každý VendorId
a poté GROUP BY
klauzule k seskupení výsledků.
Příklad 2
V tomto příkladu používáme SUM()
agregační funkce, která vrátí agregovanou populaci všech měst v okrese, pak GROUP BY
klauzule k seskupení výsledků.
Představte si, že máme tabulku s názvem City
která ukládá názvy měst a jejich obyvatel, jakož i jejich příslušné kódy zemí a okresy (v jejich vlastních samostatných sloupcích).
Takhle:
SELECT * FROM city
WHERE CountryCode IN ('AGO', 'ARE', 'AUS');
Výsledek:
+------+---------------+---------------+-----------------+--------------+ | 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 | +------+---------------+---------------+-----------------+--------------+
Výsledky jsem zredukoval na pouhé tři země, jinak by byl seznam způsob na tento článek je příliš dlouhý.
Nyní předpokládejme, že jsme chtěli získat populaci každého okresu a chtěli jsme uvést každý okres spolu s jeho populací a kódem země.
Mohli bychom to udělat.
SELECT
CountryCode,
District,
SUM(Population) AS Population
FROM City
WHERE CountryCode IN ('AGO', 'ARE', 'AUS')
GROUP BY CountryCode, District
ORDER BY CountryCode;
Výsledek:
+---------------+-----------------+--------------+ | 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 | +---------------+-----------------+--------------+
Vidíme, že naše výsledky jsou seskupeny tak, jak je uvedeno, a nyní dostáváme úplný počet obyvatel pro každý okres (na rozdíl od počtu obyvatel jednotlivých měst, jak jsou uloženy v základní tabulce).
Všimněte si, že GROUP BY
klauzule musí následovat za jakýmkoli WHERE
klauzuli a před jakýmkoli ORDER BY
doložka.
Pokud bychom chtěli získat počet obyvatel každé země namísto okresu, náš dotaz bude ještě kompaktnější.
SELECT
CountryCode,
SUM(Population) AS Population
FROM City
WHERE CountryCode IN ('AGO', 'ARE', 'AUS')
GROUP BY CountryCode
ORDER BY CountryCode;
Výsledek:
+---------------+--------------+ | CountryCode | Population | |---------------+--------------| | AGO | 2561600 | | ARE | 1728336 | | AUS | 11313666 | +---------------+--------------+
Mějte na paměti, že tato konkrétní ukázková databáze je velmi zastaralá a její počty obyvatel neodpovídají současné realitě.
Příklad 3 – Klauzule HAVING
Můžete zahrnout HAVING
klauzule s vaším GROUP BY
klauzule pro filtrování skupin.
Příklad:
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;
Výsledek:
+---------------+-----------------+--------------+ | CountryCode | District | Population | |---------------+-----------------+--------------| | AGO | Luanda | 2022000 | | AUS | New South Wales | 3993949 | | AUS | Queensland | 1805236 | | AUS | Victoria | 2990711 | | AUS | West Australia | 1096829 | +---------------+-----------------+--------------+
HAVING
klauzule je podobná klauzuli WHERE
klauzule, kromě toho WHERE
filtruje jednotlivé řádky, zatímco HAVING
skupiny filtrů.
Také WHERE
klauzule filtruje data před je seskupen, zatímco HAVING
filtruje data po je seskupena.
HAVING
klauzule přijímá stejné operátory, které můžete použít s WHERE
klauzule (například =
, ) Operator for Beginners">>
, =) Operator for Beginners">>=
, IN
, LIKE
, atd.).