Die GROUP BY-Klausel gestattet die Verwendung
eines Modifizierers WITH ROLLUP, der bewirkt,
dass zusätzliche Datensätze zur zusammenfassenden Ausgabe
hinzugefügt werden. Diese Datensätze stellen
Zusammenfassungsoperationen einer höherer Ebene (so genannte
Superaggregate) dar. ROLLUP gestattet Ihnen
auf diese Weise die Beantwortung von Fragen auf mehreren
Analyseebenen mit einer einzelnen Abfrage. Es kann
beispielsweise verwendet werden, um eine OLAP-Unterstützung
(Online Analytical Processing) zu implementieren.
Nehmen wir an, dass in einer Tabelle namens
sales die Spalten year,
country, product und
profit zur Aufzeichnung der
Vertriebsrentabilität vorhanden wären:
CREATE TABLE sales
(
year INT NOT NULL,
country VARCHAR(20) NOT NULL,
product VARCHAR(32) NOT NULL,
profit INT
);
Der Inhalt der Tabelle kann jahresbezogen wie folgt mit einer
einfachen GROUP BY-Abfrage zusammengefasst
werden:
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year;
+------+-------------+
| year | SUM(profit) |
+------+-------------+
| 2000 | 4525 |
| 2001 | 3010 |
+------+-------------+
Die Ausgabe zeigt die Gesamtrendite pro Jahr an. Wenn Sie aber auch die Rendite für den Gesamtzeitraum bestimmen wollen, müssen Sie die einzelnen Werte selbst hinzufügen oder eine zusätzliche Abfrage ausführen.
Alternativ verwenden Sie ROLLUP, wodurch sich
die beiden Analyseebenen in einer Abfrage zusammenfassen lassen.
Das Hinzufügen eines WITH
ROLLUP-Modifizierers zur GROUP
BY-Klausel bewirkt, dass die Abfrage einen anderen
Datensatz erstellt, der die Endsumme über alle vier Jahre
angibt:
mysql> SELECT year, SUM(profit) FROM sales GROUP BY year WITH ROLLUP;
+------+-------------+
| year | SUM(profit) |
+------+-------------+
| 2000 | 4525 |
| 2001 | 3010 |
| NULL | 7535 |
+------+-------------+
Die Super-Aggregat-Zeile, die die Endsumme zusammenfasst, lässt
sich am Wert NULL in der Spalte
year erkennen.
Die Wirkung von ROLLUP ist etwas komplexer,
wenn mehrere GROUP BY-Klauseln vorhanden
sind. In diesem Fall erzeugt die Abfrage jedes Mal, wenn eine
„Unterbrechung“ (also eine Wertänderung) in einer
beliebigen Spalte (mit Ausnahme der letzten Gruppenspalte)
vorhanden ist, einen Super-Aggregat-Datensatz.
So könnte etwa ohne ROLLUP eine
Zusammenfassung der Tabelle sales basierend
auf year, country und
product wie folgt aussehen:
mysql>SELECT year, country, product, SUM(profit)->FROM sales->GROUP BY year, country, product;+------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | | 2000 | USA | Calculator | 75 | | 2000 | USA | Computer | 1500 | | 2001 | Finland | Phone | 10 | | 2001 | USA | Calculator | 50 | | 2001 | USA | Computer | 2700 | | 2001 | USA | TV | 250 | +------+---------+------------+-------------+
Die Ausgabe zeigt Zusammenfassungswerte nur auf der Jahres-,
Länder- und/oder Produktebene der Analyse an. Wird nun
ROLLUP hinzugefügt, dann erzeugt die Abfrage
diverse zusätzliche Datensätze:
mysql>SELECT year, country, product, SUM(profit)->FROM sales->GROUP BY year, country, product WITH ROLLUP;+------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | Finland | NULL | 1600 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | | 2000 | India | NULL | 1350 | | 2000 | USA | Calculator | 75 | | 2000 | USA | Computer | 1500 | | 2000 | USA | NULL | 1575 | | 2000 | NULL | NULL | 4525 | | 2001 | Finland | Phone | 10 | | 2001 | Finland | NULL | 10 | | 2001 | USA | Calculator | 50 | | 2001 | USA | Computer | 2700 | | 2001 | USA | TV | 250 | | 2001 | USA | NULL | 3000 | | 2001 | NULL | NULL | 3010 | | NULL | NULL | NULL | 7535 | +------+---------+------------+-------------+
Bei dieser Abfrage bewirkt das Hinzufügen von
ROLLUP, dass die Ausgabe
Zusammenfassungsinformationen auf vier Analyseebenen (und nicht
nur auf einer) enthält. Die Ausgabe von
ROLLUP interpretieren Sie wie folgt:
Auf jede Menge von Produktdatensätzen für ein gegebenes
Jahr und Land folgend wird ein zusätzlicher Datensatz
erzeugt, der die Gesamtzahl aller Produkte angibt. Bei
diesen Datensätzen ist die Spalte
product auf NULL
gesetzt.
Auf jede Menge von Datensätzen für ein gegebenes Jahr und
Land folgend wird ein zusätzlicher Datensatz erzeugt, der
die Endsumme für alle Länder und Produkte angibt. Bei
diesen Datensätzen sind die Spalten
country und products
auf NULL gesetzt.
Abschließend wird auf alle anderen Datensätze folgend ein
zusätzlicher zusammenfassender Datensatz erzeugt, der die
Endsumme für alle Jahre, Länder und Produkte angibt. Bei
diesem Datensatz sind die Spalten year,
country und products
auf NULL gesetzt.
Weitere Aspekte der Benutzung von
ROLLUP
Die folgenden Punkte beschreiben einige für die
MySQL-Implementierung von ROLLUP spezifischen
Verhaltensweisen:
Wenn Sie ROLLUP verwenden, dürfen Sie nicht
gleichzeitig auch eine ORDER BY-Klausel zur
Sortierung der Ergebnisse einsetzen. Mit anderen Worten,
ROLLUP und ORDER BY
schließen sich gegenseitig aus. Trotzdem können Sie Einfluss
auf die Sortierreihenfolge nehmen. GROUP BY
sortiert in MySQL Ergebnisse, und Sie können die
Schlüsselwörter ASC und
DESC ausdrücklich für Spaltennamen in der
GROUP BY-Liste angeben, um die Sortierfolge
für einzelne Spalten zu spezifizieren. (Die von
ROLLUP hinzugefügten
Zusammenfassungsdatensätze höherer Ebene erscheinen ungeachtet
der Sortierfolge trotzdem erst hinter den Datensätzen, aus
denen sie berechnet wurden.)
Mit LIMIT können Sie die Anzahl der an den
Client zurückgegebenen Datensätze beschränken.
LIMIT wird nach ROLLUP
angewendet, d. h., die Beschränkung betrifft auch die
zusätzlichen Datensätze, die von ROLLUP
hinzugefügt worden sind. Zum Beispiel:
mysql>SELECT year, country, product, SUM(profit)->FROM sales->GROUP BY year, country, product WITH ROLLUP->LIMIT 5;+------+---------+------------+-------------+ | year | country | product | SUM(profit) | +------+---------+------------+-------------+ | 2000 | Finland | Computer | 1500 | | 2000 | Finland | Phone | 100 | | 2000 | Finland | NULL | 1600 | | 2000 | India | Calculator | 150 | | 2000 | India | Computer | 1200 | +------+---------+------------+-------------+
Die Verwendung von LIMIT mit
ROLLUP kann Ergebnisse erzeugen, die
schwieriger zu interpretieren sind, weil Sie weniger Kontext
haben, um die Super-Aggregate zu verstehen.
Die NULL-Indikatoren in jedem
Super-Aggregat-Datensatz werden erzeugt, wenn der Datensatz an
den Client gesendet wird. Der Server prüft alle in der
GROUP BY-Klausel genannten Spalten, die auf
die erste (am weitesten links stehende) Spalte folgen, deren
Wert geändert wurde. Bei jeder Spalte in der Ergebnismenge,
deren Name lexikalisch mit einem dieser Namen übereinstimmt,
wird der Wert auf NULL gesetzt. (Wenn Sie
Gruppenspalten über die Spaltennummer angeben, identifiziert
der Server die auf NULL zu setzenden Spalten
anhand ihrer Nummer.)
Weil die NULL-Werte in den
Super-Aggregat-Datensätzen als solche während der
Abfrageverarbeitung relativ spät in das Ergebnis eingefügt
werden, können Sie sie nicht wie NULL-Werte
innerhalb der Abfrage selbst überprüfen. So können Sie
beispielsweise HAVING product IS NULL nicht
zur Abfrage hinzufügen, um alle Datensätze mit Ausnahme der
Super-Aggregat-Datensätze aus der Ausgabe zu entfernen.
Andererseits erscheinen die NULL-Werte als
NULL auf der Clientseite und können insofern
mithilfe einer beliebigen MySQL-Clientprogrammierschnittstelle
geprüft werden.
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.
