# GROUPING SETS, ROLLUP and CUBE

More complex grouping operations than those described above are possible using the concept of grouping sets. The data selected by the FROM and WHERE clauses is grouped separately by each specified grouping set, aggregates computed for each group just as for simple GROUP BY clauses, and then the results returned. For example:

```=> SELECT * FROM items_sold;
brand | size | sales
------+------+-------
Foo   | L    | 10
Foo   | M    | 20
Bar   | M    | 15
Bar   | L    | 5
(4 rows)
=> SELECT brand, size, sum(sales) FROM items_sold GROUP BY GROUPING SETS ((brand), (size), ());
brand | size | sum
-------+------+-----
Foo |      | 30
Bar |      | 20
| L    | 15
| M    | 35
|   | 50
(5 rows)
```

Each sublist of GROUPING SETS may specify zero or more columns or expressions and is interpreted the same way as though it were directly in the GROUP BY clause. An empty grouping set means that all rows are aggregated down to a single group (which is output even if no input rows were present), as described above for the case of aggregate functions with no GROUP BY clause.

`ROLLUP ( e1, e2, e3, ... )`

represents the given list of expressions and all prefixes of the list including the empty list; thus it is equivalent to

```GROUPING SETS (
( e1, e2, e3, ... ),
...
( e1, e2 ),
( e1 ),
( )
)```

This is commonly used for analysis over hierarchical data; e.g. total salary by department, division, and company-wide total.

A clause of the form

`CUBE ( e1, e2, ... )`

represents the given list and all of its possible subsets (i.e. the power set). Thus

`CUBE ( a, b, c )`

is equivalent to

```GROUPING SETS (
( a, b, c ),
( a, b ),
( a,    c ),
( a       ),
(    b, c ),
(    b    ),
(       c ),
(         )
)```

The individual elements of a CUBE or ROLLUP clause may be either individual expressions, or sublists of elements in parentheses. In the latter case, the sublists are treated as single units for the purposes of generating the individual grouping sets. For example:

`CUBE ( (a, b), (c, d) )`

is equivalent to

```GROUPING SETS (
( a, b, c, d ),
( a, b       ),
(       c, d ),
(            )
)```

and

`ROLLUP ( a, (b, c), d )`

is equivalent to

```GROUPING SETS (
( a, b, c, d ),
( a, b, c ),
( a ),
( )
)```

The CUBE and ROLLUP constructs can be used either directly in the GROUP BY clause, or nested inside a GROUPING SETS clause. If one GROUPING SETS clause is nested inside another, the effect is the same as if all the elements of the inner clause had been written directly in the outer clause.

If multiple grouping items are specified in a single GROUP BY clause, then the final list of grouping sets is the cross product of the individual items. For example:

`GROUP BY a, CUBE (b, c), GROUPING SETS ((d), (e))`

is equivalent to

```GROUP BY GROUPING SETS (
(a, b, c, d), (a, b, c, e),
(a, b, d),    (a, b, e),
(a, c, d),    (a, c, e),
(a, d),       (a, e)
)```