1st Dec 2024 Tempo di lettura: 17 minuti Progetto SQL per principianti: Cruscotto vendite AdventureWorks Ekre Ceannmor Progetto SQL pratica su sql Indice Esplorazione del database AdventureWorks Definizione del progetto SQL Che cosa includeremo nel nostro dashboard del progetto SQL? Rapporto 1: Vendite mensili Domanda: Qual è il fatturato dell'azienda per ogni mese? Approccio Report 2: Fatturato mensile per Paese Domanda: Qual è il fatturato mensile per ogni Paese? Approccio Rapporto 3: Prodotti più venduti Domanda: Quali sono i nostri prodotti più venduti? Approccio Rapporto 4: Negozi più performanti Domanda: Quali sono i 10 negozi più venduti negli ultimi 2 mesi? Approccio Rapporto 5: Fonti di fatturato Domanda: Come si confrontano le entrate online con quelle offline? Approccio Rapporto 6: Dimensione media degli ordini per Paese Domanda: Qual è la dimensione media dell'ordine? Approccio Report 6: Valore medio dei clienti a vita per regione Domanda: Qual è il valore medio della vita del cliente in ogni regione? Approccio Crea il tuo progetto SQL per principianti! Costruire un progetto SQL per conto proprio è un ottimo modo per affinare le proprie capacità e fare esperienza pratica. Questo esempio di progetto SQL per principianti vi mostrerà come creare un cruscotto di vendita con SQL e il database di esempio AdventureWorks. Se siete principianti dell'SQL e volete andare oltre i semplici esercizi di query, è una buona idea affrontare un progetto di analisi dei dati SQL. Non solo vi sfiderà ad applicare ciò che avete imparato, ma vi darà anche una comprensione più profonda di come SQL funziona in scenari reali. Questa è l'occasione per passare dalla pratica di base alla creazione di qualcosa di tangibile che mostri la vostra crescente esperienza! In questo articolo vi guideremo attraverso le fasi di costruzione di un progetto SQL utilizzando il database AdventureWorks. Ci occuperemo di tutto, dall'idea del progetto alla scrittura delle query finali. Imparerete come affrontare ogni fase del processo e i concetti che utilizzeremo potranno essere trasferiti a qualsiasi progetto SQL. Una volta terminato, date un'occhiata al nostro corso SQL Databases for Practice, che contiene 6 diversi database con cui potrete esercitarvi a creare report. In alternativa, potete leggere come trovare set di dati gratuiti per il vostro progetto SQL e seguire il corso con il vostro database! Ora diamo un'occhiata al database che utilizzeremo in questo progetto di esempio SQL. Esplorazione del database AdventureWorks Il database AdventureWorks è un database di esempio creato da Microsoft per SQL Server. È stato portato su molti database, tra cui PostgreSQL, che utilizzeremo in questo articolo. Il database comprende 68 tabelle che descrivono un produttore di biciclette immaginario e contiene dati sui diversi tipi di transazioni che avvengono durante le operazioni commerciali. Poiché AdventureWorks è così grande, è un set di dati perfetto per i principianti che vogliono fare pratica con l'SQL in un contesto reale. Il database è suddiviso in 5 schemi, ognuno dei quali rappresenta un diverso campo di operazioni: Production, Purchasing, Sales, HR, e Person. In questo progetto, la maggior parte dei dati proverrà dallo Sales schema. Utilizzeremo anche altri schemi per ottenere alcune informazioni aggiuntive. Vediamo le tabelle che utilizzeremo di più: SalesOrderHeader: È la tabella più grande del database. Memorizza tutte le informazioni relative a un ordine nel suo complesso. Sarà il punto di partenza più comune per le interrogazioni relative alle vendite. Product: Memorizza informazioni complete sui prodotti offerti dall'azienda. SalesOrderDetail: Questa tabella collega le tabelle SalesOrderHeader e Product memorizzando le informazioni sui singoli prodotti che compongono ogni ordine. ProductReview: Memorizza le recensioni dei clienti su prodotti specifici. Store: Questa tabella contiene informazioni di base su ogni negozio. La maggior parte dei dati è memorizzata nella colonna Demographics in formato XML; non la utilizzeremo in questo progetto. SalesTerritory e CountryRegion: Utilizzeremo queste due tabelle insieme per ottenere il nome del Paese a cui è associato l'ordine. Esistono molte altre tabelle nel database, ma non preoccupatevi; le presenteremo e le loro colonne importanti quando sarà necessario. Definizione del progetto SQL In questo progetto vogliamo creare un cruscotto di vendita per AdventureWorks. Ma come si inizia un progetto del genere? Un ottimo punto di partenza è determinare l'ambito del progetto. Spesso questo significa creare un elenco di domande a cui si vuole rispondere con i dati. Il nostro elenco iniziale di domande è: Quali sono le vendite totali mensili? Quali sono le vendite mensili per Paese? Quali sono i prodotti più venduti? Quali sono i negozi che ottengono i risultati migliori? Qual è la dimensione media di ogni ordine? Qual è il valore medio di vita del cliente in ogni Paese? Man mano che ci immergiamo nei dati e scriviamo le nostre query, possiamo affinare queste domande e aggiustare le nostre query di conseguenza. Questo è il modo in cui dovreste iniziare tutti i vostri progetti SQL: scrivete un elenco delle domande che avete sui dati e poi scrivete le query che vi daranno le risposte. Man mano che si lavora sulle query e sui dati, emergeranno nuove domande. Cercate di rispondere anche a queste con le vostre query. Ora siamo pronti per iniziare a scrivere le query per il nostro dashboard delle vendite! Tenete a portata di mano il nostro SQL per principianti Cheat Sheet nel caso in cui abbiate bisogno di un rapido ripasso della sintassi. Che cosa includeremo nel nostro dashboard del progetto SQL? Rapporto 1: Vendite mensili Domanda: Qual è il fatturato dell'azienda per ogni mese? Il primo report del nostro dashboard mostra le entrate di tutti i mesi passati (per ogni anno). Questa query può essere utilizzata per tracciare linee di tendenza delle entrate, oppure può essere analizzata così com'è. Vogliamo visualizzare i dati in ordine cronologico, partendo dalle date più recenti. Approccio Innanzitutto, scegliamo la tabella su cui basare la nostra query. Vogliamo visualizzare tre colonne: l'anno e il mese di vendita e il fatturato totale per quel mese e quell'anno. Abbiamo bisogno dell'importo totale dell'ordine e della data di vendita, quindi la tabella SalesOrderHeader dello schema Sales è una scelta ovvia. Per visualizzare l'anno e il mese, utilizzeremo la funzione EXTRACT: EXTRACT(<MONTH / YEAR> FROM OrderDate) Utilizzeremo queste colonne per raggruppare e ordinare i risultati. Per ottenere le entrate totali per quel mese specifico, possiamo usare SUM(TotalDue) insieme al raggruppamento per le due colonne precedenti. In questo modo avremo risultati SUM() separati per ogni coppia anno-mese. Ecco la query finale: SELECT EXTRACT(YEAR FROM OrderDate) AS OrderYear, EXTRACT(MONTH FROM OrderDate) AS OrderMonth, ROUND(SUM(TotalDue), 2) AS TotalRevenue FROM Sales.SalesOrderHeader GROUP BY EXTRACT(YEAR FROM OrderDate), EXTRACT(MONTH FROM OrderDate) ORDER BY OrderYear DESC, OrderMonth DESC; Report 2: Fatturato mensile per Paese Domanda: Qual è il fatturato mensile per ogni Paese? Vorremmo vedere le entrate totali per ogni mese (di ogni anno) per ogni paese del database. Il risultato dovrebbe essere ordinato in ordine cronologico, con le date più recenti al primo posto. Possiamo utilizzare questi dati per tracciare linee di tendenza per ogni paese o analizzare i dati così come sono. Approccio Questa query è simile alla precedente: dobbiamo solo aggiungere le informazioni sul paese per ogni acquisto. Come possiamo farlo? La tabella SalesOrderHeader ha una colonna denominata TerritoryId, che fa riferimento alla tabella SalesTerritory tabella. Questa tabella ci dà accesso alla colonna CountryRegionCode. I nomi dei Paesi sono memorizzati nella tabella CountryRegion dello schema Person dello schema. Possiamo unire questa tabella alla tabella SalesTerritory utilizzando il codice della regione. In questo modo abbiamo un modo chiaro per espandere la nostra query. Unendo le tabelle in questo modo SalesOrderHeader -> SalesTerritory -> CountryRegion si ha accesso alla colonna CountryRegion.Name. Possiamo aggiungerla come prima colonna nell'istruzione SELECT e aggiungerla alla fine di GROUP BY e ORDER BY. Osservate la query finale: SELECT cr.Name AS Country, EXTRACT(YEAR FROM OrderDate) AS OrderYear, EXTRACT(MONTH FROM OrderDate) AS OrderMonth, ROUND(SUM(TotalDue), 2) AS TotalRevenue FROM Sales.SalesOrderHeader soh JOIN Sales.SalesTerritory st ON soh.TerritoryId = st.TerritoryId JOIN Person.CountryRegion cr ON cr.CountryRegionCode = st.CountryRegionCode GROUP BY cr.Name, EXTRACT(YEAR FROM OrderDate), EXTRACT(MONTH FROM OrderDate) ORDER BY OrderYear DESC, OrderMonth DESC, Country; Ecco una parte dell'output: CountryOrderYearOrderMonthTotalRevenue Australia201469958.82 Canada2014611471.62 France201463660.88 Germany201463818.44 Rapporto 3: Prodotti più venduti Domanda: Quali sono i nostri prodotti più venduti? Vorremmo aggiungere un elenco dei prodotti più venduti insieme ad alcune informazioni rilevanti come le vendite e le recensioni dei clienti. Il report dovrebbe mostrare dati ragionevolmente recenti. Approccio La tabella SalesOrderDetail che contiene la quantità di ogni articolo venduto, sarà il nostro punto di partenza per questa query. La costruiremo in modo incrementale. La metrica principale di questa query è la quantità totale venduta per ogni prodotto, che possiamo ottenere utilizzando la combinazione di SUM(OrderQty) e GROUP BY ProductId. Tuttavia, il risultato della query sarebbe piuttosto difficile da leggere, in quanto i prodotti sono identificabili solo attraverso il loro Id. I nomi dei prodotti sono memorizzati nella tabella Product dello schema Production schema. Unendo le due tabelle con ProductId e aggiungendo ProductName si ottiene questa query: SELECT p.ProductId, p.Name AS ProductName, SUM(od.OrderQty) AS TotalUnitsSold FROM Sales.SalesOrderDetail od JOIN Production.Product p ON od.ProductID = p.ProductID GROUP BY p.Name, p.ProductId ORDER BY TotalUnitsSold DESC LIMIT 10; ProductIdProductNameTotalUnitsSold 712AWC Logo Cap8311 870Water Bottle - 30 oz.6815 Questa query è un elemento valido del dashboard, ma può essere migliorata. Abbiamo già gettato le basi per lavorare con i prodotti. Ora vogliamo aggiungere le valutazioni ai nostri prodotti. Costruiamo una query separata, che poi uniremo alla query principale. Le recensioni dei prodotti sono memorizzate nella tabella ProductReview della tabella Production schema. A noi interessano soprattutto le ProductId e le Rating lasciate dal cliente, quindi faremo una media dei punteggi di valutazione e raggrupperemo i dati per ProductId. Ora abbiamo una mappatura uno-a-uno tra il prodotto e le sue valutazioni. Arrotondiamo il risultato a una cifra decimale, come di consueto per le recensioni: SELECT ProductId, ROUND(AVG(Rating), 1) AS ProductRating FROM Production.ProductReview GROUP BY ProductId; ProductIdProductRating 9373.0 7985.0 7095.0 Ora possiamo trasformare questa query in una Common Table Expression (CTE) da usare insieme alla nostra query principale. Le CTE sono un modo per creare un insieme di risultati temporaneo, come una tabella virtuale che esiste solo nel contesto della query. Se volete una spiegazione completa del funzionamento delle CTE, consultate la nostra guida completa alle CTE in SQL. Ora, c'è un possibile problema: potrebbero non esserci recensioni per tutti i prodotti. Quindi, quando uniamo Product dalla query principale con la CTE, assicurarsi di utilizzare un LEFT JOIN per non perdere alcun dato. Potrebbe essere utile esaminare solo i dati più recenti. Possiamo filtrare le vecchie vendite nella query principale usando la colonna OrderDate e sottrarre due mesi dalla data corrente usando INTERVAL ‘2 MONTHS’. Quindi è possibile filtrare i dati per mostrare solo gli ordini effettuati dopo tale data. Se si decide di cambiare l'intervallo di date, modificare la parte INTERVAL è abbastanza semplice. Per saperne di più sulla sintassi di INTERVAL, date un'occhiata al corsoFunzioni SQL standard . Questa è la query completa: WITH ProductRating AS ( SELECT ProductId, ROUND(AVG(Rating), 1) AS ProductRating FROM Production.ProductReview GROUP BY ProductId ) SELECT p.ProductId, p.Name AS ProductName, SUM(od.OrderQty) AS TotalUnitsSold, pr.ProductRating AS ProductRating FROM Sales.SalesOrderDetail od JOIN Sales.SalesOrderHeader oh ON od.SalesOrderId = oh.SalesOrderId JOIN Production.Product p ON od.ProductID = p.ProductID LEFT JOIN ProductRating pr ON pr.ProductId = p.ProductId WHERE OrderDate > CURRENT_DATE - INTERVAL '2 MONTH' GROUP BY p.Name, p.ProductId, pr.ProductRating ORDER BY TotalUnitsSold DESC LIMIT 10; ProductIdProductNameTotalUnitsSoldProductRating 921Mountain Tire Tube187N/A 873Patch Kit / 8 Patches181N/A 870Water Bottle - 30 oz.168N/A 922Road Tire Tube160N/A 878Fender Set - Mountain107N/A 711Sport-100 Helmet, Blue96N/A 712AWC Logo Cap95N/A 708Sport-100 Helmet, Black93N/A 923Touring Tire Tube91N/A 871Mountain Bottle Cage84N/A Questo è un elenco degno di essere visualizzato sul cruscotto di un rappresentante! La comprensione delle tendenze di vendita è qualcosa a cui ogni dipendente dovrebbe avere accesso e ora abbiamo una query che ce la fornisce. Il nostro cruscotto sta crescendo; aggiungiamo altre metriche! Rapporto 4: Negozi più performanti Domanda: Quali sono i 10 negozi più venduti negli ultimi 2 mesi? Vorremmo mostrare i primi dieci negozi, compresi quelli online, e il rispettivo aumento dei ricavi negli ultimi due mesi. Per "top store" si intende quello che ha registrato il maggior fatturato negli ultimi 2 mesi. Considerare tutti i negozi online come un'unica entità. Approccio Come di consueto, si parte dalla tabella SalesOrderHeader tabella. Per scoprire quale negozio è responsabile di una determinata vendita, osserviamo la tabella Store nello schema Sales dello schema. Ogni negozio può essere collegato a una vendita tramite la colonna SalesPersonId. Tutte le vendite in cui SalesPersonId è NULL hanno anche OnlineOrderFlag impostato su true. Questo semplificherà il lavoro di raggruppamento e di visualizzazione delle vendite online, in quanto possiamo considerare ogni vendita in cui SalesPersonId è NULL come una vendita online. Per non perdere i dati quando si uniscono le tabelle su SalesPersonId (che a volte è NULL), utilizzare un LEFT JOIN tra SalesOrderHeader e Store. Nell'istruzione SELECT ci interessano due cose: il nome del negozio e il totale delle vendite effettuate in quel negozio. Non dimenticate di avvolgere la colonna Store.Name con COALESCE(..., ‘Online’) per assicurarvi che tutti gli ordini online abbiano un'etichetta leggibile. Per filtrare i dati vecchi, utilizzare la stessa condizione WHERE dell'ultimo report: WHERE OrderDate > CURRENT_DATE - INTERVAL ‘2 MONTHS’. Ordinare i risultati in base all'importo totale delle vendite (mostrando prima i valori più grandi) e utilizzare LIMIT 10 per restituire solo i primi 10 negozi per fatturato nel periodo selezionato. Ecco la query: SELECT COALESCE(s.Name, 'Online') AS StoreName, ROUND(SUM(so.TotalDue), 2) AS TotalSalesAmount FROM Sales.SalesOrderHeader so LEFT JOIN Sales.Store s ON so.SalesPersonId = s.SalesPersonId WHERE OrderDate > CURRENT_DATE - INTERVAL '2 MONTHS' GROUP BY s.Name ORDER BY TotalSalesAmount DESC LIMIT 10; StoreNameTotalSalesAmount Online2419079.86 Friendly Bike Shop577136.64 Exceptional Cycles Services495918.62 Number One Bike Co.495918.62 Rapporto 5: Fonti di fatturato Domanda: Come si confrontano le entrate online con quelle offline? Per questa metrica del dashboard, vorremmo includere i dati relativi al numero di ordini effettuati online rispetto a quelli effettuati in negozio. I risultati finali dovrebbero essere suddivisi per mese e anno. Approccio Ancora una volta, costruiremo questa query in modo iterativo. Per suddividere le vendite in gruppi online e offline, si può utilizzare la tabella OnlineOrderFlag. Sales.SalesOrderHeader della tabella. Questa tabella include anche il prezzo totale dell'ordine, quindi questa metrica può essere calcolata da un'unica tabella. Tuttavia, il dato OnlineOrderFlag è di tipo BOOLEAN; se lo si utilizza nella clausola GROUP BY si avranno i gruppi true e false. Per rendere i dati più leggibili, possiamo usare un'espressione CASE WHEN per sostituire tutti i veri con "Online" e tutti i falsi con "Store". Poiché l'espressione OnlineOrderFlag ha già come risultato BOOLEAN, non è necessario modificarla per utilizzarla come condizione. Per una spiegazione più approfondita di come stiamo usando CASE WHEN in questo esempio, leggete la nostra guida su come usare CASE WHEN con GROUP BY. Ora che i nomi dei gruppi sono corretti, possiamo selezionare le altre metriche che mettono a confronto le fonti di guadagno: il numero totale di transazioni chiuse e il ricavo totale di tali transazioni. Il primo si ottiene semplicemente contando tutti i SalesOrderIds e il secondo sommando tutti i valori di TotalDue. Il raggruppamento può essere fatto usando il semplice OnlineOrderFlag e non l'espressione CASE WHEN; in questo caso, stiamo semplicemente mappando i valori. Ecco come appare la query attuale: SELECT CASE WHEN OnlineOrderFlag THEN 'Online' ELSE 'Store' END AS OrderOrigin, COUNT(SalesOrderId) AS TotalSales, SUM(TotalDue) AS TotalRevenue FROM Sales.SalesOrderHeader GROUP BY OnlineOrderFlag ORDER BY TotalRevenue DESC; OrderOriginTotalSalesTotalRevenue Online276593244139 Store380690775446 Possiamo vedere chiaramente una conclusione: I negozi fisici realizzano quasi 10 volte meno vendite ma producono 3 volte più ricavi dei negozi online. Possiamo rendere questi dati più significativi filtrandoli per anno e mese, in modo da vedere le tendenze dei flussi di entrate. La tabella Sales.SalesOrderHeader include la colonna OrderDate, che possiamo utilizzare per ottenere solo le parti YEAR e MONTH come abbiamo fatto nel primo report. Se aggiungiamo queste colonne supplementari e le utilizziamo in GROUP BY, vedremo che i gruppi “Store” e “Online” sono stati suddivisi in anni e mesi diversi. Possiamo inoltre filtrare le date, come abbiamo fatto in precedenza con CURRENT_DATE e INTERVAL. Ecco la query completa e un esempio dei risultati: SELECT CASE WHEN OnlineOrderFlag THEN 'Online' ELSE 'Store' END AS OrderOrigin, EXTRACT(YEAR FROM OrderDate) AS OrderYear, EXTRACT(MONTH FROM OrderDate) AS OrderMonth, COUNT(SalesOrderId) AS TotalSales, SUM(TotalDue) AS totalRevenue FROM Sales.SalesOrderHeader WHERE OrderDate > CURRENT_DATE - INTERVAL '2 MONTHS' GROUP BY EXTRACT(YEAR FROM OrderDate), EXTRACT(MONTH FROM OrderDate), OnlineOrderFlag ORDER BY OrderOrigin, OrderYear DESC, OrderMonth DESC; OrderOriginOrderYearOrderMonthTotalSalesTotalRevenue Online2014693954151,48 Store20145125843850111,69 Online201454062156071,52 Store2014421428,61 Rapporto 6: Dimensione media degli ordini per Paese Domanda: Qual è la dimensione media dell'ordine? Vorremmo visualizzare ogni paese e la dimensione media dell'ordine per tutti gli ordini provenienti da quel paese. I Paesi con una dimensione media dell'ordine maggiore dovrebbero essere mostrati per primi. Approccio Abbiamo già ottenuto il nome del Paese per ogni vendita in uno dei report precedenti, quindi possiamo concentrarci sulle dimensioni degli ordini. È importante notare che in questa query dovremo aggregare due volte: Prima per ottenere la dimensione dell'ordine per ogni ordine e poi per ottenere la media del Paese. Cominciamo con le dimensioni degli ordini. Ogni ordine può essere identificato da una voce nella tabella SalesOrderHeader tabella. Avrà più voci rispettive nella tabella SalesOrderDetail tabella corrispondenti a ciascun prodotto dell'ordine. Sommando le OrderQtys dalla tabella SalesOrderDetail per ogni SalesOrderId si ottengono le coppie numero_ordine-dimensione_ordine. Utilizzeremo un paio di JOINs per ottenere i nomi dei paesi, formando una CTE come questa: WITH OrderSizes AS ( SELECT sod.SalesOrderId, SUM(OrderQty) AS ProductCount, cr.Name AS Country FROM Sales.SalesOrderHeader soh JOIN Sales.SalesOrderDetail sod ON sod.SalesOrderId = soh.SalesOrderId JOIN Sales.SalesTerritory st ON soh.TerritoryId = st.TerritoryId JOIN Person.CountryRegion cr ON cr.CountryRegionCode = st.CountryRegionCode GROUP BY sod.SalesOrderId, cr.Name ) SELECT * FROM OrderSizes; Ora si tratta solo di ottenere la dimensione media degli ordini dalla CTE e di raggruppare il risultato per paese. Non dimenticate di ordinare i dati in modo da mostrare prima le dimensioni medie degli ordini più grandi. Date un'occhiata alla query completa e al suo risultato parziale: WITH OrderSizes AS ( SELECT sod.SalesOrderId, SUM(OrderQty) AS ProductCount, cr.Name AS Country FROM Sales.SalesOrderHeader soh JOIN Sales.SalesOrderDetail sod ON sod.SalesOrderId = soh.SalesOrderId JOIN Sales.SalesTerritory st ON soh.TerritoryId = st.TerritoryId JOIN Person.CountryRegion cr ON cr.CountryRegionCode = st.CountryRegionCode GROUP BY sod.SalesOrderId, cr.Name ) SELECT Country, ROUND(AVG(ProductCount), 2) AS AverageOrderSize FROM OrderSizes GROUP BY Country ORDER BY AverageOrderSize DESC; CountryAverageOrderSize United States12.80 Canada12.14 France7.45 United Kingdom6.24 Germany5.01 Australia2.67 Report 6: Valore medio dei clienti a vita per regione Domanda: Qual è il valore medio della vita del cliente in ogni regione? Il Customer Lifetime Value (CLV) è una metrica importante che mostra quanto l'azienda può aspettarsi che un nuovo cliente acquisito spenda durante l'intero rapporto con il marchio. Il CLV si calcola sommando i ricavi di tutti gli acquisti del cliente. È molto utile per calcolare il budget per le campagne di marketing; è meglio mostrarlo raggruppato per regione di attività. Approccio Costruiamo innanzitutto la query che calcola il CLV medio per ogni singolo cliente. Sappiamo già come viene calcolato il CLV: sommando tutti i valori di TotalDue per ogni cliente della tabella. SalesOrderHeader tabella. Questo ci darà un risultato intermedio. In seguito vogliamo raggruppare i dati per paese, quindi è utile includere anche alcuni di questi dati. La tabella Customer nello stesso schema ha una colonna TerritoryId, che possiamo utilizzare in seguito per ottenere ulteriori informazioni. Per ora, aggiungiamo TerritoryId alla query CLV come colonna aggiuntiva. Questo richiede un semplice join e un'espansione dell'istruzione GROUP BY. Ecco come appare la query finora, insieme ad alcuni risultati di esempio: SELECT cs.CustomerId, cs.TerritoryId, SUM(TotalDue) AS LifetimeRevenues FROM sales.Customer cs JOIN sales.SalesOrderheader ord ON cstm.CustomerId = ord.CustomerId GROUP BY cs.CustomerId, cs.TerritoryId; CustomerIdTerritoryIdLifetimeRevenue 26264434.56 30052421863.90 244161106.16 2674592135.37 Metà del problema è risolto. Ciò che resta da fare è raggruppare il tutto a livello di Paese e rendere il risultato più leggibile. Utilizziamo una CTE per salvare i risultati della query. Possiamo raggruppare la CTE per TerritoryId e mostrare il valore di vita medio dei clienti per territorio. Il risultato è tecnicamente corretto, anche se i territori non sono identificabili. I nomi effettivi dei paesi sono memorizzati nella tabella CountryRegion dello schema Person dello schema. È identificabile dalla chiave CountryRegionCode. Nello Sales possiamo trovare questa chiave nella tabella SalesTerritory tabella. Quindi, uniremo il risultato della CTE, attraverso la tabella SalesTerritory con la tabella CountryRegion tabella. Ora possiamo mostrare il nome del Paese invece del suo numero Id. Non dimenticare di modificare di conseguenza GROUP BY. Date un'occhiata alla query finale e ad alcuni dei suoi risultati: WITH CustomerLifetimeRevenue AS ( SELECT cstm.CustomerId, ord.TerritoryId, SUM(TotalDue) AS LifetimeRevenue FROM Sales.Customer cstm JOIN Sales.SalesOrderHeader ord ON cstm.CustomerId = ord.CustomerId GROUP BY cstm.CustomerId, ord.TerritoryId ) SELECT cr.Name AS Country, ROUND(AVG(clr.LifetimeRevenue),2) AS AvgLifetimeCustomerValue FROM CustomerLifetimeRevenue clr JOIN Sales.SalesTerritory tr ON clr.TerritoryId = tr.TerritoryId JOIN Person.CountryRegion cr ON cr.CountryRegionCode = tr.CountryRegionCode GROUP BY cr.Name ORDER BY AvgLifetimeCustomerValue DESC, cr.Name; CountryAvgLifetimeCustomerValue Canada10971.34 United States8627.27 France4403.33 United Kingdom4394.69 Australia3259.14 Germany3024.18 Crea il tuo progetto SQL per principianti! Abbiamo creato con successo query in grado di alimentare un dashboard di vendita ricco di informazioni. Tuttavia, questo articolo ha lo scopo di ispirarvi a iniziare il vostro progetto SQL. Riassumiamo come creare un progetto SQL: Trovare un set di dati interessante. Cercate un problema di business per questo set di dati, come abbiamo fatto con questo cruscotto di vendita. Scrivere le domande relative al problema a cui il progetto aiuterà a rispondere. Creare query SQL per le domande scritte. Se avete bisogno di un po' più di struttura, vi consigliamo il nostro mini-corso SQL Databases for Practice. Contiene 6 diversi database che potete utilizzare nel vostro progetto SQL, oltre ad alcune domande e suggerimenti per iniziare. Se volete vedere altri esempi di progetti SQL per principianti, date un'occhiata al nostro articolo sulla creazione di un progetto Northwind Store per il vostro portfolio. Volete fare più pratica? Date un'occhiata alla nostra enorme tracciaPratica su SQL . Buon apprendimento! Tags: Progetto SQL pratica su sql