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.