0Pricing
Coding Interview Prep · Lezione

Somme cumulative con i frame di finestra

Creare un totale progressivo usando SUM OVER con un frame ordinato

Somme cumulative con i frame di finestra è una lezione Coding Interview Prep gratuita su CoddyKit. Questa è la lezione 1 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Coding Interview Prep, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Coding Interview Prep include 4 lezioni in totale.

La domanda sul totale progressivo

Quasi ogni colloquio per analisti include una richiesta del tipo: "Mi mostri il ricavo cumulativo nel tempo?" Un totale progressivo è una somma che cresce riga dopo riga, accumulando tutto dall'inizio fino alla riga corrente.

Prima dell'introduzione delle funzioni finestra, i candidati risolvevano questo problema con un self-join lento o una sottoquery correlata. Oggi la risposta attesa è SUM(...) OVER (ORDER BY ...). Conoscere la variante basata sui frame delle finestre dimostra che comprende il moderno SQL, quello scritto a partire da circa il 2012.

Struttura di una somma su una finestra ordinata

Un totale progressivo non è altro che un'aggregazione trasformata in una funzione finestra. Mantiene SUM(amount), ma aggiunge una clausola OVER con un ORDER BY.

È l'ORDER BY all'interno di OVER a renderla cumulativa: indica a SQL di accumulare le righe in quell'ordine. Senza ORDER BY, SUM calcolerebbe il totale dell'intera partizione per ogni riga, invece di crescere progressivamente.

SELECT
  sale_date,
  amount,
  SUM(amount) OVER (ORDER BY sale_date) AS running_total
FROM sales
ORDER BY sale_date;

Perché ORDER BY implica un frame

Ecco il dettaglio che gli intervistatori amano approfondire: quando aggiunge ORDER BY a un'aggregazione su una finestra, SQL applica un frame predefinito pari a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.

È proprio questo valore predefinito a produrre un totale progressivo: ogni riga dall'inizio della partizione fino alla riga corrente, inclusa. Se comprende questo comportamento predefinito, comprende perché la somma cumulativa "funziona e basta".

Rendere esplicito il frame

Può scrivere esplicitamente il frame. Queste due query restituiscono lo stesso risultato, ma la versione esplicita mostra all'intervistatore che sa cosa succede dietro le quinte.

Scrivere ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW è la forma esplicita più sicura per un totale progressivo, perché conta le righe fisiche ed evita le sorprese del raggruppamento per valore di RANGE (trattate nella lezione successiva).

SELECT
  sale_date,
  amount,
  SUM(amount) OVER (
    ORDER BY sale_date
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) AS running_total
FROM sales;

Esempio completo: vendite giornaliere

Immagini quattro giorni di vendite: lunedì 100, martedì 50, mercoledì 200, giovedì 75. Il totale progressivo si accumula da sinistra verso destra.

  • Lun: 100
  • Mar: 100 + 50 = 150
  • Mer: 150 + 200 = 350
  • Gio: 350 + 75 = 425

L'ultima riga corrisponde sempre al totale complessivo. È un rapido controllo di coerenza che può menzionare durante un colloquio: l'ultimo valore del totale progressivo deve corrispondere a SUM(amount) calcolato sull'intero insieme.

Ripartire per gruppo con PARTITION BY

Le richieste reali vogliono solitamente un totale progressivo per cliente o per regione, non un unico totale globale. Aggiunga PARTITION BY per fare ripartire l'accumulo all'inizio di ogni partizione.

Il modello mentale è questo: PARTITION BY divide le righe in contenitori indipendenti, mentre ORDER BY e il frame vengono applicati separatamente all'interno di ciascun contenitore.

SELECT
  customer_id,
  sale_date,
  amount,
  SUM(amount) OVER (
    PARTITION BY customer_id
    ORDER BY sale_date
  ) AS customer_running_total
FROM sales;

La trappola dei valori uguali

Se due righe condividono lo stesso valore di ORDER BY (due vendite nella stessa data), il frame predefinito RANGE le considera peer e assegna loro lo stesso totale progressivo, includendo entrambi gli importi.

Se ha bisogno di un incremento rigorosamente riga per riga anche in presenza di valori uguali, passi al frame ROWS e aggiunga un criterio univoco di spareggio a ORDER BY, ad esempio sale_date, id. Gli intervistatori inseriscono appositamente date duplicate per verificare se se ne accorge.

SELECT
  sale_date,
  amount,
  SUM(amount) OVER (
    ORDER BY sale_date, id
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  ) AS running_total
FROM sales;

Totale progressivo di un conteggio

La logica cumulativa non si limita a SUM. Qualsiasi aggregazione può essere usata come funzione finestra, quindi può costruire un conteggio, una media o un massimo progressivi.

Un conteggio progressivo degli ordini è una metrica comune nei dashboard: quanti ordini abbiamo ricevuto fino a ciascun giorno?

SELECT
  order_date,
  COUNT(*) OVER (
    ORDER BY order_date
  ) AS orders_to_date
FROM orders;

Il metodo tradizionale: sottoquery correlata

A volte gli intervistatori chiedono di risolvere un totale progressivo senza funzioni finestra, per verificare la profondità delle sue conoscenze. La soluzione classica precedente alle funzioni finestra è una sottoquery correlata che ricalcola la somma di tutte le righe precedenti.

Funziona, ma ha complessità O(n al quadrato): per ogni riga esegue una nuova scansione della tabella. Lo menzioni per dimostrare che sa perché le funzioni finestra l'hanno sostituita.

SELECT
  s.sale_date,
  s.amount,
  (SELECT SUM(s2.amount)
   FROM sales s2
   WHERE s2.sale_date <= s.sale_date) AS running_total
FROM sales s
ORDER BY s.sale_date;

Filtrare il risultato della finestra

Una domanda frequente di approfondimento è: "Mostri solo i giorni in cui il totale progressivo ha superato 1000". Non può inserire una funzione finestra in WHERE, perché il frame viene calcolato dopo l'esecuzione di WHERE.

La soluzione consiste nel calcolare il totale progressivo in una CTE o in una sottoquery, per poi filtrare nella query esterna. È la stessa regola di annidamento che si applica a ogni funzione finestra.

WITH t AS (
  SELECT
    sale_date,
    SUM(amount) OVER (ORDER BY sale_date) AS running_total
  FROM sales
)
SELECT *
FROM t
WHERE running_total >= 1000;

Punti da illustrare durante il colloquio

Quando presenta una soluzione con un totale progressivo, esponga questi punti per ottenere il punteggio pieno:

  • SUM OVER (ORDER BY ...) è la forma cumulativa.
  • L'aggiunta di ORDER BY crea un frame predefinito da UNBOUNDED PRECEDING a CURRENT ROW.
  • Usi PARTITION BY per ripartire per gruppo.
  • Aggiunga un criterio univoco di spareggio e un frame ROWS per evitare la trappola dei valori duplicati.
  • Racchiuda il calcolo in una CTE per filtrare il risultato.

Verifica rapida

Verifichi la comprensione del frame predefinito.

Riepilogo: somme cumulative

Un totale progressivo è un'aggregazione ordinata su una finestra. SUM(amount) OVER (ORDER BY sale_date) accumula le righe dall'inizio della partizione fino alla riga corrente, grazie al frame implicito da UNBOUNDED PRECEDING a CURRENT ROW.

Lo faccia ripartire per gruppo con PARTITION BY, aggiunga un criterio di spareggio e un frame ROWS per gestire i valori di ordinamento duplicati e lo racchiuda in una CTE ogni volta che deve filtrare in base al valore cumulativo. Nella prossima lezione analizzeremo la distinzione tra ROWS e RANGE a cui si è accennato qui.

Domande Frequenti

La lezione «Somme cumulative con i frame di finestra» è gratuita?

Sì — il testo completo di «Somme cumulative con i frame di finestra» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Coding Interview Prep, passa a CoddyKit PRO. Il corso Coding Interview Prep include 4 lezioni in totale.

Cosa imparerò in «Somme cumulative con i frame di finestra»?

Creare un totale progressivo usando SUM OVER con un frame ordinato Eserciti Coding Interview Prep con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Coding Interview Prep?

Non è richiesta alcuna esperienza precedente. Coding Interview Prep su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 4.

Quanto tempo richiede la lezione «Somme cumulative con i frame di finestra»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Coding Interview Prep?

Sì. Ogni lezione Coding Interview Prep include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Somme cumulative con i frame di finestra
  2. Frame ROWS e RANGE
  3. Medie mobili su una finestra scorrevole
  4. Distribuzione cumulativa e percentuale del totale
← Torna a Coding Interview Prep