A prima vista, le funzioni window e le funzioni di aggregazione sembrano strumenti simili per analizzare e lavorare con i dati. Infatti, entrambe fanno calcoli come somma, media, ranking ecc. Ma vediamo bene in cosa si differenziano davvero.
Funzioni di aggregazione (GROUP BY)
Le funzioni di aggregazione funzionano così:
- Raggruppano le righe in base alle colonne che specifichi.
- Dopo il raggruppamento, ogni gruppo diventa una sola riga nel risultato.
- Esempio: vuoi sapere il totale delle vendite per ogni regione.
SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;
Particolarità: GROUP BY "comprime" i dati. Se usi il raggruppamento, tutte le righe che fanno parte di un gruppo spariscono — rimane solo il risultato dell’aggregazione.
Funzioni window (PARTITION BY)
Le funzioni window, invece:
- Mantengono la struttura originale dei dati (niente compressione o sparizione di righe!).
- Possono fare calcoli all’interno di "finestre" — gruppi logici di righe.
Esempio: vuoi sapere la quota di vendite di ogni città sul totale delle vendite della sua regione, ma senza perdere nessun dato.
SELECT
region,
city,
sales,
SUM(sales) OVER (PARTITION BY region) AS total_sales_by_region
FROM sales_data;
Particolarità: usare le funzioni window non elimina le righe, ma aggiunge solo nuovi valori calcolati a ogni riga.
Esempio: SUM() con GROUP BY vs SUM() con PARTITION BY
Per capire meglio la differenza, vediamo come SUM() funziona in entrambi i casi. Immagina di avere una tabella sales_data fatta così:
| region | city | sales |
|---|---|---|
| North | CityA | 100 |
| North | CityB | 150 |
| South | CityC | 200 |
| South | CityD | 250 |
Somma usando GROUP BY
Vogliamo sapere il totale delle vendite per ogni regione:
SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;
Il risultato sarà così:
| region | total_sales |
|---|---|
| North | 250 |
| South | 450 |
Cosa è successo: le righe sono state raggruppate per region e ogni gruppo è stato "compresso" in una sola riga con la somma delle vendite.
Somma usando PARTITION BY
Ora facciamo la stessa cosa con una funzione window:
SELECT
region,
city,
sales,
SUM(sales) OVER (PARTITION BY region) AS total_sales_by_region
FROM sales_data;
Risultato:
| region | city | sales | total_sales_by_region |
|---|---|---|---|
| North | CityA | 100 | 250 |
| North | CityB | 150 | 250 |
| South | CityC | 200 | 450 |
| South | CityD | 250 | 450 |
Cosa è successo: PARTITION BY non ha "compresso" le righe. Invece, ha calcolato la somma dentro le finestre definite (ogni regione è una finestra separata).
Quando usare GROUP BY e quando PARTITION BY?
GROUP BY: perfetto per report finali
GROUP BY è utile quando vuoi ridurre la quantità di dati e ottenere risultati finali a livello di gruppo. Per esempio:
- Vendite totali per mese.
- Conteggio degli ordini per categoria di prodotto.
Esempio:
SELECT category, COUNT(*) AS total_orders
FROM orders
GROUP BY category;
PARTITION BY: ideale per analisi e dettaglio
PARTITION BY va bene quando vuoi mantenere tutte le righe dei dati e calcolare qualcosa in più per ognuna. Per esempio:
- Calcolare la quota di vendite di ogni prodotto nella sua categoria.
- Numerare le righe dentro ogni gruppo.
Esempio di calcolo della percentuale di vendite:
SELECT
category,
product,
sales,
ROUND(
(sales * 100.0) / SUM(sales) OVER (PARTITION BY category),
2
) AS sales_percentage
FROM sales_data;
Esempio: uso di più funzioni window
Uno dei vantaggi delle funzioni window è che puoi fare più calcoli insieme. Per esempio:
SELECT
region,
city,
sales,
SUM(sales) OVER (PARTITION BY region) AS total_sales,
RANK() OVER (PARTITION BY region ORDER BY sales DESC) AS sales_rank
FROM sales_data;
Risultato:
| region | city | sales | total_sales | sales_rank |
|---|---|---|---|---|
| North | CityB | 150 | 250 | 1 |
| North | CityA | 100 | 250 | 2 |
| South | CityD | 250 | 450 | 1 |
| South | CityC | 200 | 450 | 2 |
Vantaggi delle funzioni window rispetto a GROUP BY
Mantieni i dati originali: GROUP BY "comprime" le righe, mentre le funzioni window ti permettono di mantenere la struttura originale della tabella.
Più calcoli in una sola query: Puoi usare più funzioni window con parametri diversi di PARTITION BY e ORDER BY, senza perdere dati.
Analisi flessibile: Le funzioni window ti permettono di personalizzare i calcoli come vuoi: somme cumulative, ranking, calcoli di quota e molto altro.
Esempio di flessibilità
Proviamo a combinare più funzioni:
SELECT
region,
city,
sales,
SUM(sales) OVER (PARTITION BY region) AS total_sales,
AVG(sales) OVER (PARTITION BY region) AS avg_sales,
RANK() OVER (PARTITION BY region ORDER BY sales DESC) AS rank
FROM sales_data;
Risultato:
| region | city | sales | total_sales | avg_sales | rank |
|---|---|---|---|---|---|
| North | CityB | 150 | 250 | 125.0 | 1 |
| North | CityA | 100 | 250 | 125.0 | 2 |
| South | CityD | 250 | 450 | 225.0 | 1 |
| South | CityC | 200 | 450 | 225.0 | 2 |
Limitazioni ed errori tipici
Uno degli errori più comuni è provare a usare PARTITION BY quando invece vuoi "comprimere" i dati. Per esempio, invece di:
SELECT region, SUM(sales) AS total_sales
FROM sales_data
GROUP BY region;
Qualcuno prova a scrivere così:
SELECT
region,
SUM(sales) OVER (PARTITION BY region) AS total_sales
FROM sales_data;
Ma questo ti restituirà tutte le righe, senza ridurre la quantità di dati (che non è sempre quello che vuoi).
Ora sai esattamente quando usare GROUP BY e quando invece le funzioni window. È un po’ come scegliere tra martello e cacciavite: entrambi lavorano con i chiodi... ma in modo diverso.
GO TO FULL VERSION