grouping sets

Die GROUPING SETS ()-Syntax bietet eine Generalisierung der ROLLUP- und CUBE-Funktionalität. Jede rollup()- oder cube()-Operation kann in eine GROUPING SETS-Spezifikation umgesetzt werden. Die Syntax lautet wie folgt:
GROUP BY [<set quantifier>] GROUPING SETS(<grouping-set-list>);
Dabei ist " <set quantifier> entweder DISTINCT oder ALL und standardmäßig ALL, und " <grouping-set-list> ist eine durch Komma getrennte Liste von Gruppierungssätzen, von denen jeder ein eingeklammerter " <grouping-col-list> ist, wie im folgenden Beispiel:
SELECT col1, col2, col3, COUNT(*) FROM <table> GROUP BY GROUPING SETS 
((col1,col2), (col2,col3), (col2), ());
Dieses Beispiel entspricht der simultanen Gruppierung nach den folgenden Gruppierungen:
GROUP BY (col1, col2)
GROUP BY (col2, col3)
GROUP BY col2
GROUP BY ()

Das Ergebnis der vorherigen SELECT-Anweisung entspricht dem Ergebnis einer UNION ALL-Operation für die vier Auswahlen, die auf den vier Gruppenebenen aggregiert werden. So kann eine rollup()- oder cube()-Operation in eine GROUPING SETS-Spezifikation umgesetzt werden.

Ein Eintrag in einem " <grouping-set-list> kann selbst ein " <grouping-set-list> sein, und somit auch ein " cube() oder " rollup(). Jede derartige komplexe Gruppierungssetliste kann immer in eine Gruppierungssetliste erweitert werden (siehe folgendes Beispiel):
GROUPING SETS (ROLLUP(col1,col2), CUBE(col1,col2))
Dies entspricht Folgendem:
GROUPING SETS ((col1,col2), (col1), (), (col1,col2), (col1), (col2), 
())
Mit dem folgenden eindeutigen Setquantor:
DISTINCT GROUPING SETS (ROLLUP(col1,col2), CUBE(col1,col2))
Dies ist äquivalent zu dem folgenden Beispiel, das zeigt, dass CUBE(<Liste>) eine Obermenge von ROLLUP(<Liste>) ist:
GROUPING SETS ((col1,col2), (col1), (col2), ())

Außerdem entspricht das Gruppierungsset (col1, col2) dem Gruppierungsset (col2, col1); die Eliminierung von Duplikaten in der Gruppierungssetliste erfolgt also, indem Listeneinträge in eine kanonische Form gesetzt werden, bei der eindeutige Einträge in der Reihenfolge aufgelistet werden, in der sie in der Gruppierungssetklausel auftreten.

Mehrere (nicht verschachtelte) Gruppierungssets auf derselben Ebene werden wie im folgenden Beispiel dargestellt gehandhabt:
GROUP BY GROUPING SETS ((A), (B)), GROUPING SETS ((X, Y), (Z))
Dies entspricht Folgendem:
GROUP BY GROUPING SETS ((A, X, Y), (A, Z), (B, X, Y), (B, Z))
Weiteres Beispiel:
GROUP BY A, GROUPING SETS ((X,Y), (Z))
Dies entspricht Folgendem:
GROUP BY GROUPING SETS ((A, X, Y), (A, Z))
Mit der GROUPING-Funktion können Differenzen besser unterschieden werden. Beispiel für eine Rollup-Abfrage:
STATE  |     CITY      |  SUM
_____________________________
 CA    | Los Angeles   |  600
 CA    | San Diego     |  225
 CA    | San Francisco |  450
 CA    |               | 1275
 MA    | Boston        |  460
 MA    | Springfield   |  345
 MA    |               |  805
       |               | 2080
Da einige Gruppenspaltenwerte in Superaggregatzeilen Nullwerte sind, wenn es eine NULL-Stadt gab, könnte die Unterscheidung zwischen einer Aggregatzeile und einem Superaggregat schwierig werden. Mit GROUPING (city) würde das Ergebnis eine 0 zurückgeben, wenn die Stadt in “group by” enthalten war, und eine 1, wenn die Stadt nicht enthalten war. Das folgende Beispiel zeigt das Ergebnis:
STATE  |     CITY      |  SUM  | GROUPING(city) 
_____________________________________________
 CA    | Los Angeles   |  600  |       0       
 CA    | San Diego     |  225  |       0       
 CA    | San Francisco |  450  |       0       
 CA    |               | 1275  |       1       
 MA    | Boston        |  460  |       0       
 MA    | Springfield   |  345  |       0       
 MA    |               |  805  |       1       
       |               | 2080  |       1 
Mit GROUPING (state) würde als Ergebnis eine 0 zurückgegeben, wenn der Bundesstaat in “group by” enthalten war, und eine 1, wenn der Bundesstaat nicht enthalten war. Das folgende Beispiel zeigt das Ergebnis:
STATE  |     CITY      |  SUM  | GROUPING(city)  | GROUPING(state) 
________________________________________________________________
 CA    | Los Angeles   |  600  |       0         |       0
 CA    | San Diego     |  225  |       0         |       0 
 CA    | San Francisco |  450  |       0         |       0 
 CA    |               | 1275  |       1         |       0 
 MA    | Boston        |  460  |       0         |       0 
 MA    | Springfield   |  345  |       0         |       0 
 MA    |               |  805  |       1         |       0 
       |               | 2080  |       1         |       1