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



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow