Aggregatfunktionen: COUNT, SUM, AVG
Kurz gesagt: Die Aggregatfunktionen COUNT, SUM, AVG, MIN und MAX reduzieren viele Zeilen auf einen einzigen Wert: eine Anzahl, eine Summe, einen Durchschnitt, den kleinsten oder den größten Wert.
Problem
Der Montagsbericht
Jeden Montag fragt der Inhaber dasselbe. Wie viele Kunden haben wir? Aus wie vielen Städten kommen sie? Wie viel Geld ist durch den Shop gelaufen? Was ist das teuerste Produkt?
Bisher lieferten Abfragen Zeilen. Hier brauchst du aus vielen Zeilen eine Zahl. Von Hand zählen geht nicht: Morgen sind es Tausende von Zeilen.
Die Idee
COUNT: wie viele
COUNT(*) zählt die Zeilen:
Zwanzig Zeilen gehen hinein, eine Zeile kommt heraus. Eine Funktion, die viele Zeilen in einen Wert presst, heißt Aggregatfunktion.
COUNT hat noch zwei Formen. COUNT(Spalte) zählt nur die Zeilen, in denen die Spalte nicht NULL ist. COUNT(DISTINCT Spalte) zählt die verschiedenen Werte:
20 Kunden, 19 mit Stadt (Boris hat keine) und 6 verschiedene Städte.
Probier es aus
Wie viele sind ausverkauft
Der Chef will nicht die Namen, nur die Zahl: Wie viele Produkte haben den Lagerbestand 0? Das Feld zeigt, welche. Mach daraus eine Zahl.
Lösung
SELECT COUNT(*) FROM products WHERE stock = 0;SELECT COUNT(*) FROM products WHERE stock = 0. Zwei Produkte. WHERE läuft zuerst und behält die zwei Zeilen, und COUNT(*) zählt sie.
Die Idee
SUM, AVG, MIN, MAX
Die anderen vier Funktionen arbeiten mit den Werten der Spalte:
SUM: die Summe;AVG: der Durchschnitt;MINundMAX: der kleinste und der größte Wert.
Der Umsatz ist die Summe jeder Bestellposition: Menge mal Preis.
1.963,50 €. Vorsicht: Hier sind auch die Positionen stornierter Bestellungen dabei. Welche Bestellungen storniert sind, steht in orders, die Beträge stehen in order_items. Die beiden Tabellen bringen wir im nächsten Modul mit JOIN zusammen.
Der niedrigste, der höchste und der durchschnittliche Preis der Produkte:
MIN und MAX funktionieren auch mit Text und Datumsangaben. Die erste und die letzte Bestellung:
Probier es aus
Die Bewertung des Kaffees
Die Kaffeebohnen (product_id = 17) haben eine schlechte Bewertung bekommen. Wie viele Bewertungen hat das Produkt, und wie lautet die Durchschnittsnote?
Lösung
SELECT COUNT(*), AVG(rating)
FROM reviews
WHERE product_id = 17;SELECT COUNT(*), AVG(rating) FROM reviews WHERE product_id = 17. Drei Bewertungen und ein Durchschnitt von 3,33: zwei gute (5 und 4) und eine 1.
Sieh es dir an
Eine Zeile, auch wenn nichts da ist
Ein Aggregat ohne Gruppen liefert immer eine Zeile. Die drei Positionen von Bestellung 8 werden zu einer:
Und wenn keine einzige Zeile WHERE passiert? Es gibt noch keine Bewertungen aus dem Oktober 2026:
Immer noch eine Zeile: COUNT liefert 0, und AVG liefert NULL. Es gibt nichts zu mitteln. SUM, MIN und MAX verhalten sich genauso. In einem Bericht sieht NULL wie eine leere Zelle aus, ersetze es bei Bedarf mit COALESCE(SUM(...), 0).
Sieh es dir an
AVG überspringt NULL
Wie COUNT(Spalte) überspringen auch SUM, AVG, MIN und MAX NULL. Bei AVG verändert das das Ergebnis: Du teilst nicht durch alle Zeilen, sondern durch die, die einen Wert haben.
Wie hoch ist der durchschnittliche Lagerbestand? Und der durchschnittliche Lagerbestand der Produkte, die wir wirklich haben? NULLIF(stock, 0) macht aus den Nullen NULL:
Wenn du AVG über eine Spalte mit NULL schreibst, frag dich: Sollen die leeren als null zählen? Wenn ja, AVG(COALESCE(Spalte, 0)). Wenn nicht, macht AVG(Spalte) es schon.
Übung
Zwei Berichte
1. Der Kaffeelieferant fragt, wie viele Packungen Kaffeebohnen (product_id = 17) wir verkauft haben und für wie viel Geld.
Die Stückzahl und das Geld für die Kaffeebohnen:
Lösung
SELECT SUM(quantity), SUM(quantity * unit_price)
FROM order_items
WHERE product_id = 17;SELECT SUM(quantity), SUM(quantity * unit_price) FROM order_items WHERE product_id = 17. 10 Packungen für 149 €. COUNT(*) würde hier 3 liefern: so viele Positionen, nicht Stücke.
2. Wie viele Bestellungen wurden zugestellt, und an wie viele verschiedene Kunden?
Die zugestellten Bestellungen und die verschiedenen Kunden darin:
Lösung
SELECT COUNT(*), COUNT(DISTINCT customer_id)
FROM orders
WHERE status = 'delivered';SELECT COUNT(*), COUNT(DISTINCT customer_id) FROM orders WHERE status = 'delivered'. 21 Bestellungen an 11 Kunden: Manche Kunden haben mehr als eine bekommen.
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: NULL: kein Wert · ORDER BY, LIMIT und DISTINCT · Rechnen in einer Abfrage · CASE und fehlende Werte
- Geht weiter in: GROUP BY: ein Bericht nach Gruppen · HAVING: Bedingung für Gruppen · Die Reihenfolge der Ausführung einer Abfrage · LEFT JOIN: auch Zeilen ohne Partner
- Aufgaben zum Thema: Zusammenfassen