The GROUPING SETS operator generates multiple grouping sets inside a GROUP BY.
GROUPING SETS generate subtotals for each grouping specified.
GROUPING SETS are similar to CUBE and ROLLUP (see below).
GROUPING SETS offers the most flexibility with its custom groupings.
To see how GROUPING SETS work, we'll start with a GROUP BY operation.
This example groups total sales by year.
SELECT YEAR(OrderDate) AS Year,
SUM(TotalAmount) AS 'Annual Sales'
FROM [Order]
GROUP BY YEAR(OrderDate)
ORDER BY YEAR(OrderDate)
| Year | Annual Sales |
|---|---|
| 2012 | 226298.50 |
| 2013 | 658388.75 |
| 2014 | 469771.34 |
Now we add the GROUPING SETS operator, which generates subtotals
for a GROUP BY operation. In this case two grouping sets specified are: year and the grand total.
SELECT YEAR(OrderDate) AS Year,
SUM(TotalAmount) AS 'Annual Sales'
FROM [Order]
GROUP BY GROUPING SETS(YEAR(OrderDate),())
| Year | Annual Sales |
|---|---|
| 2012 | 226298.50 |
| 2013 | 658388.75 |
| 2014 | 469771.34 |
| NULL | 1354458.59 |
This adds a summary row representing total sales over all years.
Consider the grouping columns: column1 and column2.
Here are the possible grouping sets based on these three GROUP BY subclauses.
GROUPING SETS generates a custom set of groupings from this list:
(column1, column2) (column1) (column2) ()
ROLLUP generates these grouping sets:
(column1, column2) (column1) ()
CUBE generates these grouping sets:
(column1, column2) (column1) (column2) ()
ROLLUP and CUBE have fixed groupings, whereas GROUPING SETS allows custom groupings.
Syntax of the GROUPING SETS function.
GROUP BY GROUPING SETS(set1, set2, ..., setn)
sets -- the grouping sets for which GROUPING SETS generates subtotals.
| ORDERITEM |
|---|
| Id |
| OrderId |
| ProductId |
| UnitPrice |
| Quantity |
| PRODUCT |
|---|
| Id |
| ProductName |
| SupplierId |
| UnitPrice |
| Package |
| IsDiscontinued |
| SUPPLIER |
|---|
| Id |
| CompanyName |
| ContactName |
| City |
| Country |
| Phone |
| Fax |
Again, we start with a GROUP BY statement.
This example groups total sales by supplier and product.
SELECT CompanyName, ProductName,
SUM(I.UnitPrice * I.Quantity) AS 'Total Sales'
FROM Supplier S
JOIN Product P ON S.Id = P.SupplierId
JOIN OrderItem I ON P.Id = I.ProductId
GROUP BY CompanyName, ProductName
ORDER BY CompanyName, ProductName
| CompanyName | ProductName | Total Sales |
|---|---|---|
| Aux joyeux ecclésiastiques | Chartreuse verte | 13150.80 |
| Aux joyeux ecclésiastiques | Côte de Blaye | 149984.20 |
| Bigfoot Breweries | Laughing Lumberjack Lager | 2562.00 |
| Bigfoot Breweries | Sasquatch Ale | 6678.00 |
| Bigfoot Breweries | Steeleye Stout | 14536.80 |
| Cooperativa de Quesos 'Las Cabras' | Queso Cabrales | 13902.00 |
| Cooperativa de Quesos 'Las Cabras' | Queso Manchego La Pastora | 12866.80 |
| Escargots Nouveaux | Escargots de Bourgogne | 6664.75 |
| Exotic Liquids | Aniseed Syrup | 3080.00 |
| Exotic Liquids | Chai | 14277.60 |
![]() |
||
Now we add a GROUPING SETS operator. This adds subtotals for
Supplier/Product combinations and a grand total for all sales.
SELECT CompanyName, ProductName,
SUM(I.UnitPrice * I.Quantity) AS 'Total Sales'
FROM Supplier S
JOIN Product P ON S.Id = P.SupplierId
JOIN OrderItem I ON P.Id = I.ProductId
GROUP BY GROUPING SETS((CompanyName, ProductName), (CompanyName),())
ORDER BY CompanyName, ProductName
The first row is the grand total of all sales.
Next are total sales by supplier.
Then total sales by supplier and product.
This is repeated for all suppliers.
| CompanyName | ProductName | Total Sales |
|---|---|---|
| NULL | NULL | 1354458.59 |
![]() |
||
| Aux joyeux ecclésiastiques | NULL | 163135.00 |
| Aux joyeux ecclésiastiques | Chartreuse verte | 13150.80 |
| Aux joyeux ecclésiastiques | Côte de Blaye | 149984.20 |
![]() |
||
| Bigfoot Breweries | NULL | 23776.80 |
| Bigfoot Breweries | Laughing Lumberjack Lager | 2562.00 |
| Bigfoot Breweries | Sasquatch Ale | 6678.00 |
| Bigfoot Breweries | Steeleye Stout | 14536.80 |
![]() |
||
| Zaanse Snoepfabriek | NULL | 5901.35 |
| Zaanse Snoepfabriek | Chocolade | 1542.75 |
| Zaanse Snoepfabriek | Zaanse koeken | 4358.60 |