Torna all'elenco degli articoli Articoli
Tempo di lettura: 4 minuti

Come disegnare un albero di Natale in SQL

È possibile utilizzare SQL per manipolare tutti i tipi di dati, da enormi query analitiche a brevi dichiarazioni a scopo singolo. Ma potete anche usare SQL per divertirvi, senza che i requisiti aziendali soffochino la vostra creatività. Quindi, tirate fuori il vostro cappello allegro e preparatevi a cantare O Christmas Tree, mentre creiamo un po' di arte stravagante con il vecchio SQL.

Oggi genereremo un'arte ASCII a tema natalizio, tanto per divertirci. Proprio così. Ho detto divertimento. Questo esercizio ha un valore commerciale assolutamente nullo. Se state cercando di aiutare la vostra azienda in qualche modo, a parte forse essere un dipendente allegro, è meglio che ve ne andiate, perché siamo qui per mettere alla prova le nostre abilità in SQL: disegnare alberi di Natale. Per partecipare a questa attività festiva, è necessario aver acquisito alcune competenze di base in SQL. Si spera che abbiate imparato quanto segue:

    • Funzioni stringa SQL di base
    • CTE
    • Ricorsione

Faremo affidamento su tutti e tre questi elementi per creare oggetti interessanti in SQL.

Vecchi numeri noiosi

Prima di passare alle cose più divertenti, è necessario acquisire le nozioni di base. Vorremmo generare alcuni numeri per scaldarci un po'. Esistono molti modi per generare numeri in SQL, il più comune dei quali è la ricorsione. Seguendo un semplice schema, è possibile generare una serie di numeri.

Per generare un semplice insieme di 10 numeri, possiamo scrivere la seguente CTE take10:

WITH take10(list_of_numbers) AS 
(SELECT 0 FROM DUAL
  UNION ALL 
 SELECT 
  list_of_numbers+1 
  FROM take10
  WHERE list_of_numbers < 10)
SELECT * FROM take10;

Ecco l'insieme dei risultati:

list_of_numbers
0
1
2
3
4
5
6
7
8
9
10

Nota: sto usando Oracle SQL per dimostrare i generatori, da cui l'uso della tabella doppia. Se si utilizza PostgreSQL o MySQL, sarà sufficiente una semplice clausola SELECT N senza la clausola FROM.

Piantare un albero

Va bene, basta parlare di numeri: è il momento di un po' di magia natalizia! Mi piacerebbe molto avere un bell'albero di Natale per decorare il mio SQL IDE [Integrated Development Environment - NdR] e tenermi allegro durante questa stagione uggiosa. Per generare un albero, dovremo sfruttare le funzioni stringa di SQL, che spero abbiate già sperimentato su LearnSQL.it.

Costruiremo il nostro albero utilizzando i pini e una certa profondità dell'albero:

WITH small_tree(tree_depth,pine) AS (
  SELECT 1 tree_depth,rpad(' ',10,' ') || '*' pine
  FROM   dual
  UNION ALL
  SELECT small_tree.tree_depth +1 tree_depth,
  rpad(' ',10-small_tree.tree_depth,' ') || rpad('*',small_tree.tree_depth+1,'.') || lpad('*',small_tree.tree_depth,'.') pine
  FROM   small_tree
  where small_tree.tree_depth < 10
)
SELECT pine
FROM small_tree;

Per il nostro set di risultati, otteniamo questo bell'albero di Natale:

          *
         *.*
        *...*
       *.....*
      *.......*
     *.........*
    *...........*
   *.............*
  *...............*
 *.................*

Se si desidera personalizzare il proprio albero, è sufficiente cambiare i simboli utilizzati per i pini. Se sostituiamo i pini con gli asterischi:

WITH small_tree(tree_depth,pine) AS (
  SELECT 1 tree_depth,rpad(' ',10,' ') || '.' pine
  FROM   dual
  UNION ALL
  SELECT small_tree.tree_depth +1 tree_depth,
  rpad(' ',10-small_tree.tree_depth,' ') || rpad('.',small_tree.tree_depth+1,'*') || lpad('.',small_tree.tree_depth,'*') pine
  FROM   small_tree
  where small_tree.tree_depth < 10
)
SELECT pine
FROM small_tree;

Otteniamo un albero diverso:

          .
         .*.
        .***.
       .*****.
      .*******.
     .*********.
    .***********.
   .*************.
  .***************.
 .*****************.

Se siamo in vena di festeggiamenti, possiamo generare:

WITH small_tree(tree_depth,pine) AS (
  SELECT 1 tree_depth,
  rpad(' ',10,' ') || '*' 
  || rpad(' ',20,' ') || '*' 
  || rpad(' ',20,' ') || '*' 
  pine
  FROM   dual
  UNION ALL
  SELECT small_tree.tree_depth +1 tree_depth,
  rpad(' ',10-small_tree.tree_depth,' ') || rpad('*',small_tree.tree_depth+1,'.') || lpad('*',small_tree.tree_depth,'.') 
  || rpad(' ',20-small_tree.tree_depth-tree_depth,' ') || rpad('*',small_tree.tree_depth+1,'.') || lpad('*',small_tree.tree_depth,'.') 
  || rpad(' ',20-small_tree.tree_depth-tree_depth,' ') || rpad('*',small_tree.tree_depth+1,'.') || lpad('*',small_tree.tree_depth,'.') pine
  FROM   small_tree
  where small_tree.tree_depth < 10
)
SELECT pine
FROM small_tree;

Un'intera foresta di alberi:

          *                    *                    *
         *.*                  *.*                  *.*
        *...*                *...*                *...*
       *.....*              *.....*              *.....*
      *.......*            *.......*            *.......*
     *.........*          *.........*          *.........*
    *...........*        *...........*        *...........*
   *.............*      *.............*      *.............*
  *...............*    *...............*    *...............*
 *.................*  *.................*  *.................*

Ma ai nostri alberi manca qualche ceppo! Lascio a te la sfida, caro lettore. Già che ci siamo, generiamo pure delle belle stelle e delle decorazioni: siate creativi! Quando si usa la ricorsione in SQL, l'unico limite è la propria immaginazione. Buone e festose feste dalla famiglia di LearnSQL.it!