Microsoft SQL Server
GRUPUJ WEDŁUG
Szukaj…
Proste grupowanie
Tabela zamówień
Identyfikator klienta | ID produktu | Ilość | Cena £ |
---|---|---|---|
1 | 2) | 5 | 100 |
1 | 3) | 2) | 200 |
1 | 4 | 1 | 500 |
2) | 1 | 4 | 50 |
3) | 5 | 6 | 700 |
Podczas grupowania według określonej kolumny zwracane są tylko unikalne wartości tej kolumny.
SELECT customerId
FROM orders
GROUP BY customerId;
Zwracana wartość:
Identyfikator klienta |
---|
1 |
2) |
3) |
Funkcje agregujące, takie jak count()
dotyczą każdej grupy, a nie całej tabeli:
SELECT customerId,
COUNT(productId) as numberOfProducts,
sum(price) as totalPrice
FROM orders
GROUP BY customerId;
Zwracana wartość:
Identyfikator klienta | Liczba produktów | totalPrice |
---|---|---|
1 | 3) | 800 |
2) | 1 | 50 |
3) | 1 | 700 |
Pogrupuj według wielu kolumn
Można chcieć Pogrupować według więcej niż jednej kolumny
declare @temp table(age int, name varchar(15))
insert into @temp
select 18, 'matt' union all
select 21, 'matt' union all
select 21, 'matt' union all
select 18, 'luke' union all
select 18, 'luke' union all
select 21, 'luke' union all
select 18, 'luke' union all
select 21, 'luke'
SELECT Age, Name, count(1) count
FROM @temp
GROUP BY Age, Name
pogrupuje według wieku i imienia oraz wytworzy:
Wiek | Nazwa | liczyć |
---|---|---|
18 | Łukasz | 3) |
21 | Łukasz | 2) |
18 | matowy | 1 |
21 | matowy | 2) |
Grupuj według wielu tabel, wielu kolumn
Grupowanie według jest często używane z instrukcją Join. Załóżmy, że mamy dwie tabele. Pierwsza to tabela uczniów:
ID | Pełne imię i nazwisko | Wiek |
---|---|---|
1 | Matt Jones | 20 |
2) | Frank Blue | 21 |
3) | Anthony Angel | 18 |
Druga tabela to tabela tematów, którą może wziąć każdy uczeń:
Temat_Id | Przedmiot |
---|---|
1 | Matematyka |
2) | PE |
3) | Fizyka |
Ponieważ jeden uczeń może uczęszczać na wiele przedmiotów, a na jeden przedmiot może uczęszczać wielu uczniów (dlatego relacja N: N), musimy mieć trzeci „ograniczający” stół. Nazwijmy tabelę Podmioty studentów:
Temat_Id | Legitymacja studencka |
---|---|
1 | 1 |
2) | 2) |
2) | 1 |
3) | 2) |
1 | 3) |
1 | 1 |
Powiedzmy teraz, że chcemy poznać liczbę przedmiotów, na które uczęszcza każdy uczeń. W tym przypadku samodzielna instrukcja GROUP BY
nie jest wystarczająca, ponieważ informacje nie są dostępne w pojedynczej tabeli. Dlatego musimy użyć GROUP BY
z instrukcją JOIN
:
Select Students.FullName, COUNT(Subject Id) as SubjectNumber FROM Students_Subjects
LEFT JOIN Students
ON Students_Subjects.Student_id = Students.Id
GROUP BY Students.FullName
Wynik podanego zapytania jest następujący:
Pełna nazwa | SubjectNumber |
---|---|
Matt Jones | 3) |
Frank Blue | 2) |
Anthony Angel | 1 |
Dla jeszcze bardziej złożonego przykładu użycia GROUP BY, powiedzmy, że uczeń może być w stanie przypisać ten sam temat do swojego imienia więcej niż jeden raz (jak pokazano w tabeli Student_Subjects). W tym scenariuszu możemy być w stanie policzyć, ile razy każdy przedmiot został przypisany uczniowi, grupując według więcej niż jednej kolumny:
SELECT Students.FullName, Subjects.Subject,
COUNT(Students_subjects.Subject_id) AS NumberOfOrders
FROM ((Students_Subjects
INNER JOIN Students
ON Students_Subjcets.Student_id=Students.Id)
INNER JOIN Subjects
ON Students_Subjects.Subject_id=Subjects.Subject_id)
GROUP BY Fullname,Subject
To zapytanie daje następujący wynik:
Pełna nazwa | Przedmiot | SubjectNumber |
---|---|---|
Matt Jones | Matematyka | 2) |
Matt Jones | PE | 1 |
Frank Blue | PE | 1 |
Frank Blue | Fizyka | 1 |
Anthony Angel | Matematyka | 1 |
MAJĄCY
Ponieważ klauzula WHERE
jest oceniana przed GROUP BY
, nie można użyć WHERE
do zmniejszenia wyników grupowania (zazwyczaj funkcja agregująca, taka jak COUNT(*)
). Aby spełnić tę potrzebę, można zastosować klauzulę HAVING
.
Na przykład przy użyciu następujących danych:
DECLARE @orders TABLE(OrderID INT, Name NVARCHAR(100))
INSERT INTO @orders VALUES
( 1, 'Matt' ),
( 2, 'John' ),
( 3, 'Matt' ),
( 4, 'Luke' ),
( 5, 'John' ),
( 6, 'Luke' ),
( 7, 'John' ),
( 8, 'John' ),
( 9, 'Luke' ),
( 10, 'John' ),
( 11, 'Luke' )
Gdybyśmy chcieli uzyskać liczbę zamówień złożonych przez każdą osobę, skorzystalibyśmy
SELECT Name, COUNT(*) AS 'Orders'
FROM @orders
GROUP BY Name
i dostać
Nazwa | Zamówienia |
---|---|
Matt | 2) |
Jan | 5 |
Łukasz | 4 |
Jeśli jednak chcemy ograniczyć to do osób, które złożyły więcej niż dwa zamówienia, możemy dodać klauzulę HAVING
.
SELECT Name, COUNT(*) AS 'Orders'
FROM @orders
GROUP BY Name
HAVING COUNT(*) > 2
ustąpi
Nazwa | Zamówienia |
---|---|
Jan | 5 |
Łukasz | 4 |
Zauważ, że podobnie jak GROUP BY
, kolumny umieszczone w HAVING
muszą dokładnie pasować do swoich odpowiedników w instrukcji SELECT
. Jeśli w powyższym przykładzie powiedzieliśmy zamiast tego
SELECT Name, COUNT(DISTINCT OrderID)
nasza klauzula HAVING
musiałaby powiedzieć
HAVING COUNT(DISTINCT OrderID) > 2
GROUP BY Z ROLLUP i CUBE
Operator ROLLUP jest przydatny w generowaniu raportów zawierających sumy częściowe i sumy.
CUBE generuje zestaw wyników, który pokazuje agregaty dla wszystkich kombinacji wartości w wybranych kolumnach.
ROLLUP generuje zestaw wyników, który pokazuje agregaty dla hierarchii wartości w wybranych kolumnach.
Pozycja Kolor Ilość Stół niebieski 124 Stół Czerwony 223 Krzesło niebieski 101 Krzesło Czerwony 210
SELECT CASE WHEN (GROUPING(Item) = 1) THEN 'ALL'
ELSE ISNULL(Item, 'UNKNOWN')
END AS Item,
CASE WHEN (GROUPING(Color) = 1) THEN 'ALL'
ELSE ISNULL(Color, 'UNKNOWN')
END AS Color,
SUM(Quantity) AS QtySum
FROM Inventory
GROUP BY Item, Color WITH ROLLUP
Item Color QtySum
-------------------- -------------------- --------------------------
Chair Blue 101.00
Chair Red 210.00
Chair ALL 311.00
Table Blue 124.00
Table Red 223.00
Table ALL 347.00
ALL ALL 658.00
(Dotyczy 7 wierszy)
Jeśli słowo kluczowe ROLLUP w zapytaniu zostanie zmienione na CUBE, zestaw wyników CUBE jest taki sam, z wyjątkiem tych dwóch dodatkowych wierszy zwracanych na końcu:
ALL Blue 225.00
ALL Red 433.00
https://technet.microsoft.com/en-us/library/ms189305(v=sql.90).aspx