25th Jun 2024 Tempo di lettura: 8 minuti Che cos'è un'espressione di tabella comune (CTE) in SQL? Ignacio L. Bisso sql imparare sql cte Indice Le CTE aiutano a semplificare le query Imparare le espressioni di tabella comuni di SQL tramite esempi Uso delle CTE nelle query di SQL avanzato CTE annidate nelle query SQL Query ricorsive e Espressioni di tabella comuni Le CTE di SQL sono una risorsa potente L'espressione di tabella comune (CTE) è un potente costrutto di SQL che aiuta a semplificare una query. Le CTE funzionano come tabelle virtuali (con record e colonne), create durante l'esecuzione di una query, utilizzate dalla query ed eliminate dopo l'esecuzione della stessa. Spesso le CTE fungono da ponte per trasformare i dati delle tabelle di origine nel formato previsto dalla query. Domanda: Che cos'è un'espressione di tabella comune in SQL? Una Common Table Expression (CTE) è come una sottoquery con nome. Funziona come una tabella virtuale a cui può accedere solo la query principale. Le CTE possono aiutare a semplificare, accorciare e organizzare il codice. Un'espressione di tabella comune, o CTE, è un insieme di risultati temporanei con nome creato da una semplice istruzione SELECT che può essere utilizzata in una successiva istruzione SELECT. Ogni CTE SQL è come una query denominata, il cui risultato viene memorizzato in una tabella virtuale (una CTE) a cui fare riferimento successivamente nella query principale. Il modo migliore per imparare le espressioni di tabella comuni è la pratica. Consiglio il corso interattivo di LearnSQL.itQuery ricorsive di . Contiene oltre 100 esercizi che insegnano le CTE partendo dalle basi e arrivando ad argomenti avanzati come le espressioni ricorsive di tabelle comuni. Le CTE aiutano a semplificare le query Cominciamo con la sintassi di un'espressione di tabella comune. WITH my_cte AS ( SELECT a,b,c FROM T1 ) SELECT a,c FROM my_cte WHERE .... Il nome di questa CTE è my_ctee la query CTE è SELECT a,b,c FROM T1. La CTE inizia con la parola chiave WITH, dopo la quale si specifica il nome della CTE, quindi il contenuto della query tra parentesi. La query principale viene dopo la parentesi di chiusura e fa riferimento alla CTE. In questo caso, la query principale (nota anche come query esterna) è SELECT a,c FROM my_cte WHERE …. In questo eccellente articolo introduttivo sulle CTE sono presenti molti esempi di base. Altri articoli introduttivi includono "Migliorare la leggibilità delle query con le espressioni di tabella comuni" e "Quando dovrei usare un'espressione di tabella comune (CTE)?" che spiegano le espressioni di tabella comuni. Imparare le espressioni di tabella comuni di SQL tramite esempi In questa sezione vengono presentati alcuni esempi di query SQL che utilizzano le espressioni di tabella comuni. Tutti gli esempi si basano su un database di una catena di negozi di cellulari. La tabella sales, mostrata di seguito, ha un record per ogni prodotto venduto: branchdateselleritemquantityunit_price Paris-12021-12-07CharlesHeadphones A2180 London-12021-12-06JohnCell Phone X22120 London-22021-12-07MaryHeadphones A1160 Paris-12021-12-07CharlesBattery Charger150 London-22021-12-07MaryCell Phone B2290 London-12021-12-07JohnHeadphones A0575 London-12021-12-07SeanCell Phone X12100 Nel primo esempio, otteniamo un report con gli stessi record della tabella, ma aggiungiamo una colonna in più con il nome del prodotto venduto. sales ma aggiungiamo una colonna in più con il prezzo dell'articolo più costoso venduto nella stessa filiale quel giorno. Per ottenere il prezzo dell'articolo più caro, utilizziamo una comune espressione di tabella come questa: WITH highest AS ( SELECT branch, date, MAX(unit_price) AS highest_price FROM sales GROUP BY branch, date ) SELECT sales.*, h.highest_price FROM sales JOIN highest h ON sales.branch = h.branch AND sales.date = h.date Questa query definisce una CTE SQL chiamata highest il cui risultato crea una tabella virtuale. La tabella virtuale ha le colonne filiale, data e highest_price, che contengono rispettivamente il nome della filiale, la data e il prezzo unitario più alto venduto quel giorno in questa filiale. Viene quindi eseguita la query esterna, che utilizza la tabella virtuale come se fosse una tabella regolare. highest tabella virtuale come se fosse una tabella normale. Infine, si uniscono i risultati della CTE highest con la tabella sales tabella. Il risultato dell'intera query è mostrato di seguito: branchdateselleritemquantityunit_pricehighest_ price Paris-12021-12-07CharlesHeadphones A218080 London-12021-12-06JohnCell Phone X22120120 London-22021-12-07MaryHeadphones A116090 Paris-12021-12-07CharlesBattery Charger15080 London-22021-12-07MaryCell Phone B229090 London-12021-12-07JohnHeadphones A0575100 London-12021-12-07SeanCell Phone X12100100 Nell'esempio successivo, generiamo un report con i maggiori ricavi giornalieri per filiale. WITH daily_revenue AS ( SELECT branch, date, SUM(unit_price * quantity) AS daily_revenue FROM sales WHERE EXTRACT(YEAR FROM date) = 2021 GROUP BY 1,2 ) SELECT branch, MAX(daily_revenue) max_daily_revenue FROM daily_revenue GROUP BY 1 ORDER BY 2 DESC In questa query, una CTE chiamata daily_revenue ha le colonne filiale, data e daily_revenue per ogni data del 2021. Quindi, nella query esterna, si ottiene l'importo più alto delle entrate per ogni filiale nel 2021. Il report è ordinato per max_daily_revenue in ordine decrescente. Di seguito sono riportati i risultati di questa query. branchmax_daily_revenue London-1575 London-2240 Paris-1135 Uso delle CTE nelle query di SQL avanzato È possibile definire due o più CTE e utilizzarle nella query principale. Nel prossimo esempio, mostriamo come dividere e organizzare una lunga query utilizzando le CTE SQL. Dando un nome alle diverse parti della query, le CTE ne facilitano la lettura. Supponiamo di volere un report con il fatturato mensile totale di Londra nel 2021, ma di volere anche il fatturato di ogni filiale di Londra nello stesso report. In questo caso, creiamo due CTE e le uniamo nella query principale. WITH london1_monthly_revenue AS ( SELECT EXTRACT(MONTH FROM date) as month, SUM(unit_price * quantity) AS revenue FROM sales WHERE EXTRACT(YEAR FROM date) = 2021 AND branch = 'London-1' GROUP BY 1 ), london2_monthly_revenue AS ( SELECT EXTRACT(MONTH FROM date) as month, SUM(unit_price * quantity) AS revenue FROM sales WHERE EXTRACT(YEAR FROM date) = 2021 AND branch = 'London-2' GROUP BY 1 ) SELECT l1.month, l1.revenue + l2.revenue AS london_revenue, l1.revenue AS london1_revenue, l2.revenue AS london2_revenue FROM london1_monthly_revenue l1, london2_monthly_revenue l2 WHERE l1.month = l2.month Nella query precedente, definiamo due CTE, london1_monthly_revenue e london2_monthly_revenueper ottenere le entrate mensili nel 2021 per ogni filiale di Londra. Infine, uniamo entrambe le CTE utilizzando la colonna mese e calcoliamo il fatturato totale di Londra sommando i ricavi delle due filiali. Il risultato della query è riportato di seguito: monthlondon_revenuelondon1_revenuelondon2_revenue 121055815240 Nell'esempio seguente, otteniamo un report per informare ogni filiale della data in cui è stato venduto il biglietto più grande (cioè, la quantità della combinazione articolo-quantità) e l'importo di questo biglietto. A tal fine, è necessario creare una CTE che classifica i biglietti (la colonna position è la classifica) per ogni filiale in base all'importo del biglietto. WITH tickets AS ( SELECT distinct branch, date, unit_price * quantity AS ticket_amount, ROW_NUMBER() OVER ( PARTITION BY branch ORDER by unit_price * quantity DESC ) AS position FROM sales ORDER BY 3 DESC ) SELECT branch, date, ticket_amount FROM tickets WHERE position =1 Nella query precedente, creiamo una CTE con le colonne branch, date, ticket_amount e position. Poi, nella query esterna, filtriamo solo i record con position = 1 per ottenere ciò che vogliamo, il biglietto più grande per ramo. Il risultato della query è mostrato di seguito: branchdateticket_amount London-12021-11-2450 London-22021-11-1270 Paris-12021-12-780 CTE annidate nelle query SQL Il prossimo esempio mostra una CTE annidata. L'idea è quella di generare un report con tutti gli articoli di prezzo superiore a 90 dollari e la quantità di questi articoli venduti dalla filiale Londra-2. WITH over_90_items AS ( SELECT DISTINCT item, unit_price FROM sales WHERE unit_price >=90 ), london2_over_90 AS ( SELECT o90.item, o90.unit_price, coalesce(SUM(s.quantity), 0) as total_sold FROM over_90_items o90 LEFT JOIN sales s ON o90.item = s.item AND s.branch = 'London-2' GROUP BY o90.item, o90.unit_price ) SELECT item, unit_price, total_sold FROM london2_over_90; La prima CTE è over_90_itemsche seleziona tutti gli articoli con prezzo maggiore o uguale a 90 dollari. La seconda CTE è london2_over_90che seleziona la quantità venduta da Londra-2 per ogni articolo incluso in over_90_items. Questa query ha una CTE annidata - si noti il FROM nella seconda CTE che fa riferimento alla prima. Si usa LEFT JOIN sales perché Londra-2 potrebbe non aver venduto tutti gli articoli presenti in . over_90_items. Il risultato della query è: itemunit_pricetotal_sold Cell Phone X11000 Cell Phone X21200 Cell Phone B2907 Prima di passare alla sezione successiva, ho alcuni articoli da suggerire sulle espressioni di tabella comuni. Sia "SQL CTEs Explained with Examples" che "Where Can I Find Good SQL CTE Exercises?" contengono molti esempi ed esercizi. Query ricorsive e Espressioni di tabella comuni Nei database relazionali è comune avere tabelle che rappresentano gerarchie di dati come dipendenti-gestori, parti-sottoparti o genitori-figli. Per attraversare queste gerarchie in qualsiasi direzione (dall'alto verso il basso o dal basso verso l'alto), i database utilizzano un costrutto chiamato CTE ricorsivo. RECURSIVE è una parola riservata per definire una CTE per l'attraversamento di una struttura di dati ricorsiva. La forma della query ricorsiva è la seguente: WITH RECURSIVE cte_name AS ( CTE_query_definition -- non recursive query term UNION ALL CTE_query_definition -- recursive query term ) SELECT * FROM cte_name; Le query ricorsive esulano dallo scopo di questo articolo introduttivo, ma ne ho altri tre da suggerire a chi vuole approfondire l'argomento: "Come organizzare le query SQL con le CTE", "Fallo in SQL: L'attraversamento ricorsivo di alberi in SQL" e "Conoscerela potenza di SQL Query ricorsive", che spiegano in dettaglio le query ricorsive con molti esempi. Le CTE di SQL sono una risorsa potente Le espressioni di tabella comuni sono una potente risorsa del linguaggio SQL. Permettono di creare query più leggibili e di gestire le differenze di formato tra i dati delle tabelle e quelli dei report. In questo articolo abbiamo spiegato cos'è una CTE e come utilizzarla in diversi tipi di query. Abbiamo anche accennato al fatto che le CTE possono essere utilizzate nelle query ricorsive. Consiglio il corso Query ricorsive all'indirizzo LearnSQL.itdove si impara in modo interattivo a lavorare con le espressioni di tabella comuni in SQL. Si impara anche a elaborare strutture di dati ricorsive come grafi e alberi in SQL utilizzando le CTE ricorsive. Inoltre, date un'occhiata alla traccia SQL avanzatoin cui si va oltre le nozioni di base per diventare un maestro di SQL. Se avete bisogno di prepararvi per un colloquio SQL, c'è un interessante articolo "Top 5 SQL CTE Interview Questions" che tratta le comuni espressioni di tabella da un'altra prospettiva. Se avete imparato a usare le CTE, siete già un passo avanti nel percorso che vi porterà a diventare uno sviluppatore SQL. Continuate a crescere! Tags: sql imparare sql cte