Abfragen: Aggregation

Manchmal möchte man Daten erfassen, die sich aus mehreren Zeilen zusammensetzen, z.B. den durschnittlichen Preis aller Bücher. Man sagt auch, dass über mehrere Zeilen aggregiert wird. Betrachte die folgende bekannte Tabelle buch aus der onlineshop-Datenbank.

Zurückgegeben wird dann nur eine einzige Zeile. Stelle dir das so vor, dass die ganze Tabelle „zusammengefaltet“ wird. Welche Informationen sind in dieser Zeile enthalten? Das hängt von de Aggregatsfunktionen ab, die du verwendest. Hier direkt ein Beispiel.

SELECT AVG(preis) FROM buch

Es ist auch möglich, mehrere Aggregatsfunktionen in einer Abfrage zu verwenden. Pro Aggregatsfunktion wird eine eigene Spalte erzeugt. Weiterhin wird jedoch nur eine einzelne Zeile zurückgeliefert. In folgendem Beispiel wird der niedrigste Buchpreis, der durchschnittliche Buchpreis und der höchste Buchpreis ermittelt.

SELECT MIN(preis) AS niedrigster_preis,
       AVG(preis) AS durchschnittlicher_preis,
       MAX(preis) AS hoechster_preis
FROM   buch

Im Folgenden sind die wichtigsten Aggregatsfunktionen aufgelistet.

Name Beispiel Bedeutung
MIN MIN(preis) Nimmt das Minimum aller Werte der Spalte preis
MAX MAX(preis) Nimmt das Maximum aller Werte der Spalte preis
AVG AVG(preis) Nimmt das arithmethische Mittel aller Werte der Spalte preis (en. average: „durchschnittlich“)
SUM SUM(preis) Nimmt die Summe aller Werte in der Spalte preis
COUNT COUNT(*) Zählt die Anzahl an Zeilen. (für uns: bitte immer auf ganze Zeilen * anwenden)

Manchmal möchte man die Aggregation (also z.B. das Berechnen des Durchschnittpreises) nicht über die gesamte Tabelle durchführen, sondern pro Genre. Man erhält dann z.B. jeweils einen Durchschnittspreis für das Genre Fantasy, Kinderliteratur etc.

Bevor die Tabelle zu einer Zeile „zusammengefaltet“ wird, besteht zu diesem Zweck die Möglichkeit, die Zeilen zu gruppieren mit der GROUP BY-Klausel. Hier direkt ein Beispiel, bei dem der Durchschnittspreis pro Genre ermittelt wird.

SELECT genre, AVG(preis)
FROM   buch
GROUP BY genre

Die Klausel GROUP BY genre gruppiert die Zeilen nach Genre: Alle Zeilen mit demselben Genre werden in einer Gruppe zusammengefasst. Über diese Gruppen wird dann aggregiert. Statt wie vorher nur eine Zeile zurückzugeben, wird nun pro Genre eine Zeile zurückgegeben. Die Spalte, über die aggregiert wurde, darf nun auch in der SELECT-Klausel stehen.

Sehr fortgeschritten (nicht klausurrelevant):

Die Zeilen, die nach einer Aggregation mit Gruppierung zurückgeliefert werden, können nochmals gefiltert werden. Hierfür wird die HAVING-Klausel verwendet. Um z.B. die Durchschnittspreise für jedes Genre zu erhalten, jedoch nur solche, bei denen dieser Durchschnittspreis über 12 € liegt, kann folgende Abfrage verwendet werden.

SELECT genre, AVG(preis)
FROM   buch
GROUP BY genre
HAVING AVG(preis) > 12