Microsoft SQL Server
GRUPPIERE NACH
Suche…
Einfache Gruppierung
Bestellungstabelle
Kundennummer | Produkt ID | Menge | Preis |
---|---|---|---|
1 | 2 | 5 | 100 |
1 | 3 | 2 | 200 |
1 | 4 | 1 | 500 |
2 | 1 | 4 | 50 |
3 | 5 | 6 | 700 |
Bei der Gruppierung nach einer bestimmten Spalte werden nur eindeutige Werte dieser Spalte zurückgegeben.
SELECT customerId
FROM orders
GROUP BY customerId;
Rückgabewert:
Kundennummer |
---|
1 |
2 |
3 |
Aggregatfunktionen wie count()
gelten für jede Gruppe und nicht für die vollständige Tabelle:
SELECT customerId,
COUNT(productId) as numberOfProducts,
sum(price) as totalPrice
FROM orders
GROUP BY customerId;
Rückgabewert:
Kundennummer | Anzahl der Produkte | totalPreis |
---|---|---|
1 | 3 | 800 |
2 | 1 | 50 |
3 | 1 | 700 |
GROUP BY mehrere Spalten
Möglicherweise möchten Sie GROUP BY mehr als eine Spalte
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
wird nach Alter und Namen gruppiert und produziert:
Alter | Name | Anzahl |
---|---|---|
18 | luke | 3 |
21 | luke | 2 |
18 | matt | 1 |
21 | matt | 2 |
Gruppieren mit mehreren Tabellen, mehreren Spalten
Group by wird oft mit der join-Anweisung verwendet. Nehmen wir an, wir haben zwei Tabellen. Der erste ist der Schultisch:
Ich würde | Vollständiger Name | Alter |
---|---|---|
1 | Matt Jones | 20 |
2 | Frank Blue | 21 |
3 | Anthony Angel | 18 |
Die zweite Tabelle ist die Tabelle, die jeder Student belegen kann:
Subject_Id | Gegenstand |
---|---|
1 | Mathe |
2 | PE |
3 | Physik |
Und da ein Schüler viele Fächer besuchen kann und ein Fach von vielen Schülern besucht werden kann (daher N: N-Beziehung), müssen wir einen dritten "Begrenzungstisch" haben. Nennen wir die Tabelle Students_subjects:
Subject_Id | Studenten ID |
---|---|
1 | 1 |
2 | 2 |
2 | 1 |
3 | 2 |
1 | 3 |
1 | 1 |
Nehmen wir an, wir möchten wissen, wie viele Fächer jeder Schüler besucht. Hier ist die eigenständige GROUP BY
Anweisung nicht ausreichend, da die Informationen nicht über eine einzige Tabelle verfügbar sind. Daher müssen wir GROUP BY
mit der JOIN
Anweisung verwenden:
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
Das Ergebnis der angegebenen Abfrage lautet wie folgt:
Vollständiger Name | Betreffnummer |
---|---|
Matt Jones | 3 |
Frank Blue | 2 |
Anthony Angel | 1 |
Für ein noch komplexeres Beispiel für die Verwendung von GROUP BY kann der Student seinem Namen möglicherweise mehr als einmal das gleiche Thema zuweisen (wie in der Tabelle Students_Subjects gezeigt). In diesem Szenario können wir möglicherweise zählen, wie oft jedes Subjekt einem Schüler von GROUPing durch mehr als eine Spalte zugewiesen wurde:
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
Diese Abfrage liefert das folgende Ergebnis:
Vollständiger Name | Gegenstand | Betreffnummer |
---|---|---|
Matt Jones | Mathe | 2 |
Matt Jones | PE | 1 |
Frank Blue | PE | 1 |
Frank Blue | Physik | 1 |
Anthony Angel | Mathe | 1 |
HABEN
Da die WHERE
Klausel vor GROUP BY
ausgewertet wird, können Sie WHERE
nicht verwenden, um die Ergebnisse der Gruppierung (in der Regel eine Aggregatfunktion, wie z. B. COUNT(*)
), zu COUNT(*)
. Um diesem Bedarf HAVING
, kann die HAVING
Klausel verwendet werden.
Verwenden Sie beispielsweise folgende Daten:
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' )
Wenn wir die Anzahl der Bestellungen erhalten möchten, die jede Person aufgegeben hat, würden wir sie verwenden
SELECT Name, COUNT(*) AS 'Orders'
FROM @orders
GROUP BY Name
und bekomme
Name | Aufträge |
---|---|
Matt | 2 |
John | 5 |
Luke | 4 |
Wenn wir dies jedoch auf Personen beschränken möchten, die mehr als zwei Bestellungen HAVING
haben, können wir eine HAVING
Klausel hinzufügen.
SELECT Name, COUNT(*) AS 'Orders'
FROM @orders
GROUP BY Name
HAVING COUNT(*) > 2
wird nachgeben
Name | Aufträge |
---|---|
John | 5 |
Luke | 4 |
Beachten Sie, dass die Spalten, die in HAVING
werden, genau wie GROUP BY
genau ihren Entsprechungen in der SELECT
Anweisung entsprechen müssen. Wenn wir im obigen Beispiel stattdessen gesagt hätten
SELECT Name, COUNT(DISTINCT OrderID)
Unsere HAVING
Klausel müsste sagen
HAVING COUNT(DISTINCT OrderID) > 2
GROUP BY mit ROLLUP und CUBE
Der ROLLUP-Operator ist nützlich, um Berichte zu generieren, die Zwischensummen und Summen enthalten.
CUBE generiert eine Ergebnismenge, in der Aggregate für alle Wertekombinationen in den ausgewählten Spalten angezeigt werden.
ROLLUP generiert eine Ergebnismenge, die Aggregate für eine Hierarchie von Werten in den ausgewählten Spalten anzeigt.
Artikel Farbe Menge Tabelle Blau 124 Tabelle rot 223 Stuhl Blau 101 Stuhl rot 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
(7 Zeile (n) betroffen)
Wenn das ROLLUP-Schlüsselwort in der Abfrage in CUBE geändert wird, ist die CUBE-Ergebnismenge gleich, mit Ausnahme dieser beiden zusätzlichen Zeilen werden am Ende zurückgegeben:
ALL Blue 225.00
ALL Red 433.00
https://technet.microsoft.com/de-de/library/ms189305(v=sql.90).aspx