Talvolta voglio eseguire una query che mi fornisca dei risultati aggregati di media, min, max… ma anche dei risultati sull’intero rowset senza aggregazione. Per avere questo risultato SQL Server (ma anche PostgreSQL e MySQL) posso usare la clausola ROLLUP. Per esempio assumiamo di avere la classica relazione dipartimento, impiegati e salari, vogliamo, per prima cosa, ottenere, per ogni dipartimento, la media dei salari. Utilizzo la classica clausola GROUP BY in questo modo:

SELECT Department, AVG(Salary) as AvgSalary
FROM Employees
GROUP BY Department

Ottenendo:

DepartmentAvgSalary
Sales78,500.00
Marketing81,250.00
IT55,000.50
Executive91,900.75

Voglio, nella stessa query, sapere quale è il salario medio per l’intera compagnia su tutti i dipartimenti: utilizzo la parola chiave ROLLUP per eseguire il comando (AVG in questo caso) su tutti i dati indipendentemente dal raggruppamento.

SELECT Department, AVG(Salary) as AvgSalary
FROM Employees
GROUP BY Department
WITH ROLLUP
DepartmentAvgSalary
Sales78,500.00
Marketing81,250.00
IT55,000.50
Executive91,900.75
NULL76,662.81

Notare che è stata aggiunta un’ultima riga che identifica la media totale senza raggruppameno, la cui chiave, che identifica il dipartimento, è NULL. Posso rilevare questa riga e sostituire il NULL con una descrizione più parlante utilizzando, nella SELECT, il comando GROUPING(columnName) che fornisce valore 1 quando la colonna selezionata è un raggruppamento. Usando quindi il comando CASE posso ottenere l’output desiderato:

SELECT
CASE
WHEN GROUPING(Department) = 1 THEN 'Company Average'
ELSE Department
END AS Department,
AVG(Salary) as AvgSalary
FROM Employees
GROUP BY Department
WITH ROLLUP
DepartmentAvgSalary
Sales78,500.00
Marketing81,250.00
IT55,000.50
Executive91,900.75
Company Average76,662.81