Aggregatfunktionen

to aggregate (engl.): anhäufen, vereinigen.

Jede Tabelle lässt sich nach einer Spalte gruppieren. Dabei werden alle Datensätze zu einer Gruppe zusammengefasst, die in der angegebenen Spalte denselben Wert haben. Mit einer Abfrage kann zunächst nur diese Spalte über eine Projektion ausgegeben werden.

Mithilfe von Aggregatfunktionen kann die Tabelle um zusätzlich mit neuen Informationen erweitert werden.
Diese Funktionen beziehen sich entweder
  • auf die gesamte Selektion einer Anfrage oder
  • auf Gruppen von Datensätzen, die mit GROUP BYCOUNT(), SUM(), AVG(), MAX() und MIN()-
SQL92 spezifiziert die fünf Aggregatfunktionen.

1. SUM()

SUM() summiert die Werte einer Spalte (gegebenenfalls innerhalb einer Gruppe).

Beispiel: Tabelle Kasseneinnahmen

ID KundenID Beschreibung Betrag
1 33 Ersatzgebühr 40
2 33 Mitgliederbeitrag 50
3 45 Mitgliederbeitrag 50
4 33 Mahngebühr 65
5 35 Kaution 20
6 59 Ersatzgebühr 40
7 45 Mahngebühr 80
8 45 Ersatzgebühr 40

Hier geben wir zu jeder Beschreibung einen eigenen summierten Betrag aus.
SELECT Beschreibung, SUM(Betrag)
FROM Kasseneinnahmen
GROUP BY Beschreibung;
Ergebnis:

Beschreibung SUM(Betrag)
Ersatzgebühr 120
Mitgliederbeitrag 100
Mahngebühr 145
Kaution 20

2. AVG()

AVG() berechnet pro Gruppe die Durchschnittswerte:
SELECT Beschreibung, AVG(Betrag)
FROM Kasseneinnahmen
GROUP BY Beschreibung;
Ergebnis:

Beschreibung AVG(Betrag)
Ersatzgebühr 40
Mitgliederbeitrag 50
Mahngebühr 72.5
Kaution 20

3. und 4. MAX() und MIN()

MIN() und MAX() geben pro Gruppe die Minimal- und Maximalwerte aus:
SELECT Beschreibung, MIN(Betrag), MAX(Betrag)
FROM Kasseneinnahmen
GROUP BY Beschreibung;
Ergebnis:
Beschreibung MIN(Betrag) MAX(Betrag)
Ersatzgebühr 40 40
Mitgliederbeitrag 50 50
Mahngebühr 65 80
Kaution 20 20

MAX() und MIN() können aber auch auf nicht-numerische Spalten angewandt werden und suchen in diesem Fall nach der alphabetischen Ordnung oder nach der Datumsreihenfolge den Maximal- bzw. Minimalwert in einer Spalte. Schaue Dir dazu ein Beispiel unten an, in dem für die Tabelle Kasseneinnahmen die alphabetisch höchsten und niedrigsten Werte geliefert werden.
SELECT MIN(Beschreibung), MAX(Beschreibung)
FROM Kasseneinnahmen;


MIN(Beschreibung) MAX(Beschreibung)
Ersatzgebühr Mitgliederbeitrag

5. Count()

COUNT() listet die Anzahl der Datensätze pro Gruppe auf:
SELECT Beschreibung, COUNT(Betrag)
FROM Kasseneinnahmen
GROUP BY Beschreibung;
Ergebnis:

Beschreibung COUNT(Betrag)
Ersatzgebühr 3
Mitgliederbeitrag 2
Mahngebühr 2
Kaution 1

Wie bereits beschrieben, ist es auch möglich, die gesamte Tabelle (oder die gesamte Ergebnisrelation) als eine Gruppe zu betrachten und insgesamt die Summe, den Durchschnittswert, den Minimal- und Maximalwert sowie die Anzahl auszugeben, indem man die Gruppierung ganz weg lässt:
SELECT SUM(Betrag), AVG(Betrag), MIN(Betrag), MAX(Betrag), COUNT(Betrag)
FROM Kasseneinnahmen;


SUM(Betrag) AVG(Betrag) MIN(Betrag) MAX(Betrag) COUNT(Betrag)
385 48.125 20 80 8

NULL_Werte

NULL-Werte bei Aggregatfunktionen liefern auch dann Ergebnisse, wenn einige der Werte einer Gruppe den Wert NULL enthalten. Die fehlenden Einträge werden in der Endsumme nicht berücksichtigt. Wir verändern zur Veranschaulichung die Tabelle Kasseneinnahmen so, dass zwei Einträge NULL-Werte in der Spalte für Beträge enthalten, und führen noch einmal die obige SELECT-Anfrage aus.

Kasseneinnahmen:

ID KundenID Beschreibung Betrag
1 33 Ersatzgebühr 40
2 33 Mitgliederbeitrag 50
3 45 Mitgliederbeitrag 50
4 33 Mahngebühr NULL
5 35 Kaution NULL
6 59 Ersatzgebühr 40
7 45 Mahngebühr 80
8 45 Ersatzgebühr 40


SELECT SUM(Betrag), AVG(Betrag), MIN(Betrag), MAX(Betrag), COUNT(Betrag)
FROM Kasseneinnahmen;
Ergebnis:

SUM(Betrag) AVG(Betrag) MIN(Betrag) MAX(Betrag) COUNT(Betrag)
300 50 40 80 6

Steht der NULL-Wert in der Spalte, welche die Gruppierung bestimmt, wird dies als eine weitere Gruppe interpretiert. Hier ein Beispiel:

ID KundenID Beschreibung Betrag
1 33 Ersatzgebühr 40
2 33 Mitgliederbeitrag 50
3 45 Mitgliederbeitrag 50
4 33 Mahngebühr NULL
5 35 Kaution NULL
6 59 Ersatzgebühr 40
7 45 Mahngebühr 80
8 45 Ersatzgebühr 40
9 33 NULL 35
10 59 NULL 45


SELECT Beschreibung, SUM(Betrag), AVG(Betrag)
FROM Kasseneinnahmen GROUP BY Beschreibung;
Ergebnis:

Beschreibung SUM(Betrag) AVG(Betrag)
NULL 80 40
Mahngebühr 80 80
Kaution NULL NULL
Mitgliederbeitrag 100 50
Ersatzgebühr 120 40

Die Besonderheiten von COUNT()

Bei allen Aggregatfunktionen ist NULL also ein Wert, welcher unerwartete Folgen auf das Ergebnis haben kann. Die einzige Standard-Aggregatfunktion, welche die Option der Berücksichtigung von NULL-Werten anbietet, ist COUNT(). COUNT() kann das so genannte Wildcardzeichen "*" verwenden, um die Berücksichtigung der NULL-Werte zu erzwingen. Außerdem bietet sie mit den Schlüsselwörtern DISTINCT und ALL einige Anfragemöglichkeiten, die es bei den anderen Aggregatfunktionen nicht gibt. Sehen wir uns zuerst das Syntaxdiagramm zu den Standard-Aggregatfunktionen in SQL92 an.

Systaxdiagramm

Hier sind einige Beispiele, die wir auf die etwas veränderte Tabelle Kasseneinnahmen anwenden.

Kasseneinnahmen

ID Kunde Beschreibung Betrag
1 Betz Ersatzgebühr 40
2 Betz Mitgliederbeitrag 50
3 Polak Mitgliederbeitrag 50
4 Betz Mahngebühr NULL
5 Kampinski Kaution NULL
6 Mayer Ersatzgebühr 40
7 Polak Mahngebühr 80
8 Polak Ersatzgebühr 40
9 Betz NULL 35
10 Mayer Ersatzgebühr 45
11 Mayer NULL 45


  Mit Wildcard * Ohne Wildcard
Anfrage SELECT COUNT(*), Beschreibung FROM Kasseneinnahmen
GROUP BY Beschreibung;
SELECT COUNT(Betrag), Beschreibung FROM Kasseneinnahmen
GROUP BY Beschreibung;
Ergebnis
COUNT(*) Beschreibung
4 Ersatzgebühr
1 Kaution
2 Mahngebühr
2 Mitgliederbeitrag
2  
COUNT(Betrag) Beschreibung
4 Ersatzgebühr
0 Kaution
1 Mahngebühr
2 Mitgliederbeitrag
2  
Wie man sieht, werden bei dem Ergebnis ohne Wildcard die Datensätze mit dem Wert NULL in der Spalte "Betrag" nicht in die Zählung einbezogen.

DISTINCT und ALL

Wenn man das Syntaxdiagramm genau betrachtet, wird auffallen, dass bei den Standard- Aggregatfunktionen innerhalb der Klammer die Schlüsselwörter DISTINCT und ALL verwendet werden können. ALL ist die Voreinstellung, falls keines der beiden angegeben wurde, und bedeutet, dass Wiederholungen innerhalb der Aggregatfunktion berücksichtigt werden. DISTINCT dagegen unterdrückt jegliche Wiederholung. Man könnte beispielsweise wissen wollen, zu wie vielen verschiedenen Beschreibungen jeder Kunde eingezahlt hat.


  Mit DISTINCT MIT ALL
Anfrage SELECT COUNT(DISTINCT Beschreibung), Kunde
FROM Kasseneinnahmen
GROUP BY Kunde;
SELECT COUNT(ALL Beschreibung), Kunde
FROM Kasseneinnahmen
GROUP BY Kunde;
Ergebnis
COUNT(DISTINCT Beschreibung) Kunde
3 Betz
3 Polak
1 Kampinski
1 Mayer
COUNT(ALL Beschreibung) Kunde
3 Betz
3 Polak
1 Kampinski
2 Mayer
Beachte den Eintrag für "Mayer" in beiden Ergebnissen. Links liegt der Wert, den COUNT() liefert, bei 1, rechts bei 2. "Mayer" hat zweimal "Ersatzgebühr" zahlen müssen. DISTINCT unterdrückt die Wiederholung, also wissen wir, dass die Tabelle für "Mayer" Einträge mit nur einer Art von Beschreibung enthält (in diesem Fall ist es "Ersatzgebühr"). Mit ALL wird jedes einzelne Vorkommen einer Beschreibung berücksichtigt; also auch, dass Mayer zweimal die "Ersatzgebühr" hat zahlen müssen. Die Einträge mit NULL-Werten werden nicht berücksichtigt, da keine Wildcard "*" verwendet wird. DISTINCT macht bei den anderen vier Standard-Aggregatfunktionen selten einen Sinn. SUM(DISTINCT Betrag) gruppiert nach den Beschreibungen. Mayer würde nur eine Gebühr von Euro 45,- zahlen, auch wenn es mehrere Zahlungen in dieser Höhe geben würde, wie folgendes Beispiel demonstriert:

Kasseneinnahmen


ID Kunde Beschreibung Betrag
1 Betz Ersatzgebühr 40
2 Betz Mitgliederbeitrag 50
3 Polak Mitgliederbeitrag 50
4 Betz Mahngebühr NULL
5 Kampinski Kaution NULL
6 Mayer Ersatzgebühr 40
7 Polak Mahngebühr 80
8 Polak Ersatzgebühr 40
9 Betz NULL 35
10 Mayer Ersatzgebühr 45
11 Mayer NULL 45


SELECT SUM(DISTINCT Betrag), Kunde
FROM Kasseneinnahmen
GROUP BY Kunde;
Ergebnis:
SUM(DISTINCT BETRAG) KUNDE
125 Betz
NULL Kampinski
85 Mayer
170 Polak
Es wird mit der obigen SELECT-Anfrage jede Zahl in der Gruppe der Kunden nur einmal zur Gesamtsumme gerechnet. Für die drei Einträge von "Mayer" bedeutet dies, dass der Eintrag 6 in Spalte ID mit "40" und einer der Einträge 10 oder 11 in Spalte ID (aber nicht beide) zur Gesamtsumme "85" berechnet wird. Es gibt selten eine Anwendung, die solche Geschäftsbedingungen erfordert.

Weitere Aggregatfunktionen

Außer den Standard-Aggregatfunktionen, die in SQL92 spezifiziert sind, implementieren die Hersteller einige weitere Funktionen wie STDDEV() für die Standard-Abweichung und VARIANCE() für die Streuung. MySQL implementiert sogar Aggregatfunktionen für die bitweise Verknüpfung von Zahlenwerten; dies sind allerdings Funktionen für sehr ausgefallene Anwendungen, die in einem Einführungskurs kaum Platz haben, weshalb wir hier auf eine nähere Beschreibung verzichten werden.