Generare serie di numeri e date
Usare la ricorsione per produrre sequenze utili a colmare lacune e creare calendari
Generare serie di numeri e date è una lezione Coding Interview Prep gratuita su CoddyKit. Questa è la lezione 3 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.
Ricorsione senza gerarchie
Le CTE ricorsive non servono solo per gli alberi. Un secondo impiego importante è la generazione di sequenze: una serie di numeri oppure ogni data compresa in un intervallo. Gli intervistatori propongono questo tipo di problema quando è necessario il riempimento dei gap, cioè produrre righe che non esistono in alcuna tabella.
La richiesta classica è: "Mostrare le vendite per ogni giorno del mese, inclusi i giorni con vendite pari a zero." Non è possibile mostrare un giorno mancante se prima non si generano tutti i giorni.
Una semplice serie numerica
Il membro anchor inizializza il primo numero; il membro ricorsivo ne aggiunge uno a ogni iterazione; una clausola WHERE nel membro ricorsivo lo arresta. In questo modo si generano i numeri da 1 a 10.
WITH RECURSIVE nums AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM nums WHERE n < 10
)
SELECT n FROM nums;Il predicato di terminazione
A differenza dell'organigramma, una serie numerica non ha una foglia naturale a cui fermarsi: si potrebbe incrementare il valore all'infinito. È quindi necessario aggiungere una condizione di arresto esplicita nel membro ricorsivo: WHERE n < 10.
Quando n raggiunge 10, il WHERE dell'iterazione successiva filtra l'unica riga candidata, il membro ricorsivo non restituisce alcun risultato e la ricorsione si arresta. Dimenticare questo controllo è la causa principale della ricorsione senza fine nei colloqui.
Parametrizzazione dell'intervallo
Renda la serie flessibile ricavando il limite da un valore o da una variabile. In questo esempio si generano i numeri da 1 a N, dove N viene fornito dall'esterno. La stessa struttura permette di produrre serie con base 0 o con incrementi regolari: basta modificare il valore iniziale e l'incremento.
WITH RECURSIVE nums AS (
SELECT 1 AS n
UNION ALL
SELECT n + 2 FROM nums WHERE n + 2 <= 99
)
SELECT n FROM nums; -- odd numbers 1,3,5,...,99Generazione di una serie di date
Sostituendo l'aritmetica degli interi con quella delle date si ottiene un calendario. Il membro anchor è la data iniziale; il membro ricorsivo aggiunge un giorno finché non supera la data finale.
La sintassi per aggiungere un giorno varia in base al dialetto: questa forma in stile Postgres usa un intervallo.
WITH RECURSIVE cal AS (
SELECT DATE '2024-01-01' AS d
UNION ALL
SELECT d + INTERVAL '1 day'
FROM cal
WHERE d < DATE '2024-01-31'
)
SELECT d FROM cal;Riempimento dei gap con un LEFT JOIN
Ora si combinano il calendario e i dati reali. Si genera ogni giorno, quindi si esegue un LEFT JOIN con la tabella delle vendite, in modo che i giorni mancanti compaiano con un valore NULL, trasformato in 0 tramite COALESCE.
Questo schema in due passaggi, cioè generare la spina dorsale e poi eseguire un left join con i dati, è il cuore di ogni soluzione per il riempimento dei gap.
WITH RECURSIVE cal AS (
SELECT DATE '2024-01-01' AS d
UNION ALL
SELECT d + INTERVAL '1 day' FROM cal
WHERE d < DATE '2024-01-07'
)
SELECT cal.d, COALESCE(SUM(s.amount), 0) AS total
FROM cal
LEFT JOIN sales s ON s.sale_date = cal.d
GROUP BY cal.d
ORDER BY cal.d;Strutture di riferimento mensili e settimanali
Modifichi l'incremento per creare calendari con una granularità maggiore. Aggiunga INTERVAL '1 month' per una struttura di riferimento mensile oppure INTERVAL '7 day' per una struttura settimanale. È utile quando un intervistatore richiede un report mensile che includa anche i mesi vuoti.
WITH RECURSIVE months AS (
SELECT DATE '2024-01-01' AS m
UNION ALL
SELECT m + INTERVAL '1 month' FROM months
WHERE m < DATE '2024-12-01'
)
SELECT m FROM months;Differenze tra dialetti nell'aritmetica delle date
L'aritmetica delle date è la parte meno portabile di queste query. È importante conoscere le varianti:
- Postgres:
d + INTERVAL '1 day'. - MySQL:
DATE_ADD(d, INTERVAL 1 DAY). - SQL Server:
DATEADD(DAY, 1, d). - SQLite:
date(d, '+1 day').
Precisare che la struttura della ricorsione è identica e che cambia solo la funzione per le date dimostra una solida consapevolezza dei diversi dialetti.
Ricorsione e generate_series
Postgres include la funzione integrata generate_series(), che produce numeri o date senza ricorrere alla ricorsione, in modo più rapido e chiaro:
SELECT generate_series(DATE '2024-01-01', DATE '2024-01-31', INTERVAL '1 day');
Se il database dell'intervistatore la supporta, è preferibile usarla. Tuttavia, molti engine, tra cui MySQL e SQL Server nelle versioni precedenti a quelle più recenti, non la includono: è proprio in questi casi che la CTE ricorsiva costituisce l'alternativa portabile.
Attenzione al limite della ricorsione
La generazione di una serie molto ampia può raggiungere il limite di ricorsione dell'engine. SQL Server ha per impostazione predefinita MAXRECURSION 100, quindi un calendario di 365 giorni fallisce se non si aggiunge OPTION (MAXRECURSION 0) per rimuovere il limite.
Postgres non ha un limite fisso, ma una serie senza fine dovuta a un predicato errato può continuare fino a esaurire la memoria. Prima di aumentare la scala, verifichi sempre che il predicato di terminazione sia corretto.
-- SQL Server: lift the 100-row recursion cap
-- ...recursive CTE here...
SELECT * FROM cal
OPTION (MAXRECURSION 0);Eseguire un CROSS JOIN con la serie
Una serie generata è spesso solo un componente. Una volta ottenuta una CTE di numeri, è possibile eseguire un CROSS JOIN per espandere o moltiplicare le righe, ad esempio per ripetere ogni riga di un ordine in base alla relativa quantità oppure per distribuire un intervallo di date per ogni cliente.
Riconoscere che la ricorsione produce un elemento costitutivo riutilizzabile, non solo una risposta finale, è ciò che distingue una risposta raffinata in un colloquio da una risposta imparata a memoria.
WITH RECURSIVE nums AS (
SELECT 1 AS n
UNION ALL
SELECT n + 1 FROM nums WHERE n < 10
)
SELECT o.order_id, nums.n AS unit
FROM orders o
JOIN nums ON nums.n <= o.quantity;Verifica rapida
Perché il predicato di arresto è fondamentale in una serie di numeri o di date?
Riepilogo
La ricorsione può creare righe che non esistono in alcuna tabella:
- Si inizializza il primo valore nell'anchor e lo si incrementa nel membro ricorsivo.
- Si aggiunge sempre un predicato di terminazione esplicito: le serie non hanno una fine naturale.
- Si crea una spina dorsale di date o numeri, quindi si esegue un
LEFT JOINcon i dati e si usaCOALESCEper riempire i gap. - Si preferisca
generate_seriesquando disponibile e si presti attenzione aMAXRECURSIONin SQL Server.
Successivamente: le tecniche di sicurezza che impediscono alla ricorsione di continuare senza fine.
Domande Frequenti
La lezione «Generare serie di numeri e date» è gratuita?
Sì — il testo completo di «Generare serie di numeri e date» è 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 «Generare serie di numeri e date»?
Usare la ricorsione per produrre sequenze utili a colmare lacune e creare calendari 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 3 di 4.
Quanto tempo richiede la lezione «Generare serie di numeri e date»?
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
- Membri anchor e ricorsivi
- Attraversare un organigramma
- Generare serie di numeri e date
- Evitare la ricorsione infinita