W SQL GROUP BY
Klauzula może być użyta do podzielenia wyników zapytania na grupy wierszy.
Odbywa się to zwykle w celu wykonania jednej lub więcej agregacji w każdej grupie.
Przykład 1
Oto przykład demonstrujący GROUP BY
klauzula.
Weź poniższą tabelę:
SELECT * FROM Products;
Wynik:
+-------------+------------+---------------------------------+----------------+-----------------------------------------+ | 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. | +-------------+------------+---------------------------------+----------------+-----------------------------------------+
Moglibyśmy uruchomić następujące zapytanie w tej tabeli.
SELECT
VendorId,
COUNT(VendorId) AS Count
FROM Products
GROUP BY VendorId;
Wynik:
+------------+---------+ | VendorId | Count | |------------+---------| | 1001 | 3 | | 1002 | 1 | | 1003 | 2 | | 1004 | 1 | +------------+---------+
Tutaj używamy COUNT()
funkcja agregująca zwracająca liczbę wierszy dla każdego VendorId
, a następnie GROUP BY
klauzula grupująca wyniki.
Przykład 2
W tym przykładzie używamy SUM()
funkcja agregująca zwracająca zagregowaną populację wszystkich miast w okręgu, a następnie GROUP BY
klauzula grupująca wyniki.
Wyobraź sobie, że mamy tabelę o nazwie City
przechowuje nazwy miast i ich populację, a także ich odpowiednie kody krajów i dzielnice (w osobnych kolumnach).
Tak:
SELECT * FROM city
WHERE CountryCode IN ('AGO', 'ARE', 'AUS');
Wynik:
+------+---------------+---------------+-----------------+--------------+ | 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 | +------+---------------+---------------+-----------------+--------------+
Ograniczyłem wyniki do zaledwie trzech krajów, w przeciwnym razie lista byłaby droga za długi na ten artykuł.
Załóżmy teraz, że chcielibyśmy uzyskać populację każdego okręgu i chcieliśmy wymienić każdy okręg wraz z jego populacją i kodem kraju.
Moglibyśmy to zrobić.
SELECT
CountryCode,
District,
SUM(Population) AS Population
FROM City
WHERE CountryCode IN ('AGO', 'ARE', 'AUS')
GROUP BY CountryCode, District
ORDER BY CountryCode;
Wynik:
+---------------+-----------------+--------------+ | 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 | +---------------+-----------------+--------------+
Widzimy, że nasze wyniki są pogrupowane zgodnie z opisem, a teraz otrzymujemy pełną populację dla każdej dzielnicy (w przeciwieństwie do populacji poszczególnych miast, która jest przechowywana w tabeli poniżej).
Zauważ, że GROUP BY
klauzula musi znajdować się po każdym WHERE
klauzula i przed dowolnym ORDER BY
klauzula.
Gdybyśmy chcieli uzyskać populację każdego kraju zamiast okręgu, nasze zapytanie staje się jeszcze bardziej zwarte.
SELECT
CountryCode,
SUM(Population) AS Population
FROM City
WHERE CountryCode IN ('AGO', 'ARE', 'AUS')
GROUP BY CountryCode
ORDER BY CountryCode;
Wynik:
+---------------+--------------+ | CountryCode | Population | |---------------+--------------| | AGO | 2561600 | | ARE | 1728336 | | AUS | 11313666 | +---------------+--------------+
Należy pamiętać, że ta konkretna przykładowa baza danych jest bardzo nieaktualna, a jej populacje nie odzwierciedlają obecnej rzeczywistości.
Przykład 3 – Klauzula MIEĆ
Możesz dołączyć HAVING
klauzula z Twoim GROUP BY
klauzula do filtrowania grup.
Przykład:
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;
Wynik:
+---------------+-----------------+--------------+ | CountryCode | District | Population | |---------------+-----------------+--------------| | AGO | Luanda | 2022000 | | AUS | New South Wales | 3993949 | | AUS | Queensland | 1805236 | | AUS | Victoria | 2990711 | | AUS | West Australia | 1096829 | +---------------+-----------------+--------------+
HAVING
klauzula jest podobna do WHERE
klauzula, z wyjątkiem tego, że WHERE
filtruje poszczególne wiersze, natomiast HAVING
filtruje grupy.
Ponadto WHERE
klauzula filtruje dane przed jest zgrupowany, podczas gdy HAVING
filtruje dane po jest zgrupowany.
HAVING
Klauzula akceptuje te same operatory, których można używać z WHERE
klauzula (np. =
, ) Operator for Beginners">>
, =) Operator for Beginners">>=
, IN
, LIKE
itp.).