CodeGym /Corsi /SQL SELF /Errori tipici nell'uso delle funzioni window

Errori tipici nell'uso delle funzioni window

SQL SELF
Livello 30, Lezione 4
Disponibile

È arrivato il momento di parlare delle difficoltà che possono saltare fuori quando si lavora con le funzioni window. Come spesso succede nella programmazione (e nella vita), è meglio imparare dagli errori degli altri. Vediamo insieme gli errori più comuni che fanno i principianti (e a volte pure i dev più esperti) e impariamo a evitarli.

Errore n°1: Uso sbagliato di PARTITION BY

Uno degli errori più frequenti è dimenticarsi o impostare male il parametro PARTITION BY, soprattutto se vuoi dividere i dati in gruppi. Senza di lui, PostgreSQL considera tutte le righe come un unico grande gruppo, e i risultati potrebbero essere molto diversi da quello che ti aspetti.

Supponiamo di avere una tabella sales che contiene dati sulle vendite:

id region month total
1 North 2023-01 1000
2 South 2023-01 800
3 North 2023-02 1200
4 South 2023-02 900

Vuoi trovare la somma cumulativa (SUM()) delle vendite per mese per ogni regione. Puoi scrivere una query così:

SELECT
    region,
    month,
    SUM(total) OVER (ORDER BY month) AS running_total
FROM 
    sales;

Risultato:

region month running_total
North 2023-01 1000
South 2023-01 1800
North 2023-02 3000
South 2023-02 3900

A prima vista sembra tutto ok. Ma il risultato chiaramente non è quello che ci si aspetta, perché la somma cumulativa viene calcolata su tutte le righe, non per regione. Il problema è che ci siamo dimenticati di aggiungere PARTITION BY region.

Codice corretto:

SELECT 
    region,
    month,
    SUM(total) OVER (PARTITION BY region ORDER BY month) AS running_total
FROM 
    sales;

Risultato:

region month running_total
North 2023-01 1000
North 2023-02 2200
South 2023-01 800
South 2023-02 1700

Ora tutto funziona come si deve: i dati sono raggruppati per regione e la somma cumulativa viene calcolata separatamente per ogni regione.

Errore n°2: Ordine sbagliato in ORDER BY

ORDER BY dentro OVER() controlla l'ordine delle righe nella finestra. Se l'ordine è sbagliato, i risultati saranno strani.

Vuoi trovare le somme cumulative delle vendite ordinate in ordine decrescente di mese. Puoi scrivere una query così:

SELECT
    month,
    total,
    SUM(total) OVER (ORDER BY month DESC) AS running_total
FROM 
    sales;

Risultato:

month total running_total
2023-02 1200 1200
2023-02 900 2100
2023-01 1000 3100
2023-01 800 3900

A prima vista sembra tutto giusto, ma occhio: le righe sono raggruppate per mese, ma la somma non viene calcolata correttamente a causa dell'ordine decrescente. Ecco perché i risultati sono confusi.

Correzione: riscrivi la query usando l'ordine giusto in ORDER BY:

SELECT
    month,
    total,
    SUM(total) OVER (ORDER BY month ASC) AS running_total
FROM 
    sales;

Errore n°3: Uso delle funzioni window senza indici

Le funzioni window spesso lavorano con grandi quantità di dati, e la mancanza di indici sulle colonne chiave può portare a performance disastrose.

Esempio: abbiamo una tabella large_sales con milioni di righe e vogliamo calcolare i rank delle vendite:

SELECT
    id,
    total,
    RANK() OVER (ORDER BY total DESC) AS rank
FROM 
    large_sales;

Su pochi dati la query va veloce, ma su grandi volumi può metterci una vita.

Correzione: aggiungi un indice sulla colonna usata in ORDER BY:

CREATE INDEX idx_total ON large_sales(total DESC);

Ora la query andrà molto più veloce.

Errore n°4: Non capire la finestra definita da ROWS o RANGE

Quando usi ROWS e RANGE è importante capire come calcolano la finestra delle righe. Capire male queste parole chiave può portare a risultati inaspettati.

Esempio: vuoi calcolare la media mobile delle vendite per il mese corrente e i due precedenti:

SELECT
    month,
    AVG(total) OVER (ORDER BY month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM 
    sales;

Se invece di ROWS usi RANGE:

SELECT
    month,
    AVG(total) OVER (ORDER BY month RANGE BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM 
    sales;

Il risultato sarà diverso, perché RANGE lavora sui range di valori, non su un numero preciso di righe.

Errore n°5: Uso eccessivo delle funzioni window

Usare più funzioni window nella stessa query può causare calcoli duplicati e rallentare tutto.

Esempio:

SELECT 
    id,
    total,
    SUM(total) OVER (PARTITION BY region) AS region_total,
    SUM(total) OVER (PARTITION BY region) / COUNT(total) OVER (PARTITION BY region) AS region_avg
FROM 
    sales;

Qui SUM(total) e COUNT(total) vengono calcolati più volte per ogni riga.

Correzione: accorcia la query usando subquery o CTE:

WITH cte_region_totals AS (
    SELECT 
        region,
        SUM(total) AS region_total,
        COUNT(total) AS region_count
    FROM 
        sales
    GROUP BY 
        region
)
SELECT 
    s.id,
    s.total,
    t.region_total,
    t.region_total / t.region_count AS region_avg
FROM 
    sales s
JOIN 
    cte_region_totals t ON s.region = t.region;

Consigli per evitare errori

Controlla PARTITION BY e ORDER BY: assicurati sempre che la finestra sia impostata correttamente.

Indicizza i dati: soprattutto se usi ordinamenti (ORDER BY) o filtri.

Usa i CTE per calcoli ripetuti: così eviti di ripetere gli stessi passaggi.

Guarda il piano di esecuzione: usa EXPLAIN e EXPLAIN ANALYZE per capire come PostgreSQL esegue la query.

Testa sui dati reali: assicurati che i risultati siano quelli che ti aspetti e che il problema sia risolto davvero.

2
Compito
SQL SELF, livello 30, lezione 4
Bloccato
Utilizzo di ORDER BY nelle funzioni finestra
Utilizzo di ORDER BY nelle funzioni finestra
1
Sondaggio/quiz
Configurazione del frame finestra, livello 30, lezione 4
Non disponibile
Configurazione del frame finestra
Configurazione del frame finestra
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION