Premium

Gruppierung, der GROUP BY-Operator

Lass uns eine Query ausführen:

MySQL 8.1
SELECT id, home_type, has_tv, price FROM Rooms;
idhome_typehas_tvprice
1Private room1149
2Entire home/apt0225
3Private room1150
4Entire home/apt189
5Entire home/apt080
6Entire home/apt0200
7Private room060
8Private room179
9Private room179
10Entire home/apt1150
11Entire home/apt1135
12Private room085
13Private room089
14Private room085
15Entire home/apt1120
40Shared room140
idhome_typehas_tvprice
1Private roomtrue149
2Entire home/aptfalse225
3Private roomtrue150
4Entire home/apttrue89
5Entire home/aptfalse80
6Entire home/aptfalse200
7Private roomfalse60
8Private roomtrue79
9Private roomtrue79
10Entire home/apttrue150
11Entire home/apttrue135
12Private roomfalse85
13Private roomfalse89
14Private roomfalse85
15Entire home/apttrue120
40Shared roomtrue40

So bekommen wir Infos zu jeder einzelnen vermieteten Unterkunft. Aber was, wenn wir nicht jede einzelne Zeile sehen wollen, sondern Informationen über die Gruppen, die sie bilden?

Solche Gruppen könnten zum Beispiel die Datensätze sein, aufgeteilt nach Unterkunftstyp:

  • Shared room (Zimmer für mehrere Personen mieten)
  • Private room (ein eigenes Zimmer mieten)
  • Entire home/apt (eine komplette Wohnung mieten)

Diese Gruppen enthalten unterschiedliche Datensätze und haben entsprechend unterschiedliche Eigenschaften, die sehr nützlich sein können.

Solche nützlichen Informationen über Gruppen können sein:

  • der durchschnittliche Mietpreis für ein Zimmer oder eine komplette Unterkunft
  • die Anzahl der vermieteten Unterkünfte pro Typ

Genau dafür gibt es den GROUP BY-Operator.

Allgemeine Struktur einer Query mit GROUP BY

MySQL 8.1
SELECT [Literale, Aggregatfunktionen, Gruppierungsfelder]
FROM tabellen_name
GROUP BY gruppierungsfelder;

Damit unsere Datensätze nach Unterkunftstyp gruppiert werden, müssen wir nach GROUP BY das Feld home_type angeben – also das Feld, nach dem gruppiert wird.

MySQL 8.1
SELECT home_type FROM Rooms
GROUP BY home_type
home_type
Private room
Entire home/apt
Shared room

Beachte: Bei GROUP BY werden alle NULL-Werte als gleich behandelt. Wird also nach einem Feld gruppiert, das NULL-Werte enthält, landen alle diese Zeilen in einer einzigen Gruppe.

Mit GROUP BY arbeiten wir nicht mehr mit einzelnen Datensätzen, sondern mit den gebildeten Gruppen. Deshalb können wir nicht einfach beliebige Felder aus einem Datensatz ausgeben (zum Beispiel has_tv oder price), wie wir das vorher konnten. Denn in jeder Gruppe können mehrere Datensätze stehen, und jeder davon kann in diesem Feld einen anderen Wert haben.

Mit GROUP BY darfst du nur folgende Dinge ausgeben:

  • Literale, also explizit angegebene feste Werte.

    Die kannst du ausgeben, weil es feste Werte sind, die von nichts abhängen. Zum Beispiel:

    MySQL 8.1
    SELECT home_type, 'literal' FROM Rooms
    GROUP BY home_type
    
    home_typeliteral
    Private roomliteral
    Entire home/aptliteral
    Shared roomliteral
  • Ergebnisse von Aggregatfunktionen, also berechnete Werte auf Basis einer Wertemenge.

    Aggregatfunktionen behandeln wir ausführlich in der nächsten Lektion. Zur Veranschaulichung schauen wir uns aber kurz AVG an. AVG nimmt als Argument den Namen des Feldes, für das wir den Durchschnitt pro Gruppe berechnen wollen.

    MySQL 8.1
    SELECT home_type, AVG(price) as avg_price FROM Rooms
    GROUP BY home_type
    
    home_typeavg_price
    Private room89.4286
    Entire home/apt148.6667
    Shared room40

    Die ausgeführte Query teilt alle Datensätze aus Rooms zunächst anhand von home_type in 3 Gruppen auf. Dann summiert sie für jede Gruppe alle Werte aus dem Feld price der jeweiligen Datensätze und teilt das Ergebnis durch die Anzahl der Datensätze in dieser Gruppe.

  • Gruppierungsfelder.

    Die kannst du ausgeben, weil die Werte der Felder, nach denen gruppiert wird, innerhalb einer Gruppe identisch sind.

Gruppierung nach 2 und mehr Feldern

Wir haben gesehen, wie die Datensätze einer Tabelle nach einem Feld gruppiert werden. Zur Veranschaulichung sieht es bei einer Gruppierung nach home_type etwa so aus:

Gruppierung nach einem Feld

Beim Gruppieren nach 2 oder mehr Feldern bleibt das Prinzip dasselbe, nur werden die gebildeten Gruppen zusätzlich anhand des zweiten Gruppierungsfeldes weiter unterteilt.

Beispiel für eine Gruppierung nach home_type und has_tv:

Gruppierung nach zwei Feldern

Wollen wir uns selbst testen? Was kann mit GROUP BY in einem SELECT ausgegeben werden?