SQL - Istruzioni di selezione
Transcript
SQL - Istruzioni di selezione
SmartLab - DITEN - Università di Genova http://smartlab.ws SQL - Istruzioni di selezione - Nested query Dr. Alessandro Ghio [email protected] 1 Interrogazioni nidificate (nested query) http://smartlab.ws • Una nested query (o interrogazione nidificata) è un’istruzione di selezione contenuta all’interno di un’altra istruzione di selezione • Viene utilizzata per suddividere un problema complesso in due o più problemi più semplici • Spesso una nested query potrebbe essere sostituita da una join, che spesso risulterebbe però più complessa • È possibile introdurre nested query nelle clausole FROM, WHERE e HAVING 2 Esempio http://smartlab.ws • Consideriamo nuovamente il DB esercizio1 • Vogliamo visualizzare i codici dei prodotti aventi lo stesso nome del prodotto avente codice 90 3 Esempio http://smartlab.ws • Consideriamo nuovamente il DB esercizio1 • Vogliamo visualizzare i codici dei prodotti aventi lo stesso nome del prodotto avente codice 90 • Come primo passo, ci conviene quindi selezionare il nome del prodotto avente codice 90 4 Esempio http://smartlab.ws • Consideriamo nuovamente il DB esercizio1 • Vogliamo visualizzare i codici dei prodotti aventi lo stesso nome del prodotto avente codice 90 • Come primo passo, ci conviene quindi selezionare il nome del prodotto avente codice 90 • È quindi sufficiente selezionare tutti i codici il cui corrispondente nome è uguale a quello estratto dalla prima query 5 Esempio http://smartlab.ws 6 Esempio http://smartlab.ws • Abbiamo lo stesso problema che avevamo con la join sulla stessa tabella • Dati ripetuti • Possiamo usare lo stesso trucchetto usato all’epoca (eliminare i dati che hanno lo stesso ID cercato) 7 Esempio http://smartlab.ws • Lo stesso risultato possiamo ovviamente ottenerlo con una inner join • Vediamo come derivarla a partire dalla query nidificata p1 p2 8 Esempio http://smartlab.ws • Lo stesso risultato possiamo ovviamente ottenerlo con una inner join • Vediamo come derivarla a partire dalla query nidificata p1.Nome = p2.Nome 9 Esempio http://smartlab.ws • Lo stesso risultato possiamo ovviamente ottenerlo con una inner join • Vediamo come derivarla a partire dalla query nidificata p2.IdProdotto p1.IdProdotto = 90 p2.IdProdotto <> 90 10 Esempio http://smartlab.ws • Lo stesso risultato possiamo ovviamente ottenerlo con una inner join • Vediamo come derivarla a partire dalla query nidificata 11 Esempio http://smartlab.ws • Visualizzare il codice dei prodotti il cui costo unitario è inferiore alla media dei costi unitari di tutti i prodotti nel DB • In questo caso, trovare una formulazione equivalente tramite join è pressoché impossibile a causa della funzione di aggregazione 12 Operatore IN http://smartlab.ws • Nel primo esempio abbiamo potuto applicare una semplice operazione di uguaglianza in quanto coscienti del fatto che il risultato della query nidificata consistesse in un singolo valore • Quando, invece, la query nidificata restituisce una relazione (un set di dati) e vogliamo selezionare dati da questo subset filtrando ulteriormente, possiamo sfruttare la clausola IN 13 Operatore IN - Esempio http://smartlab.ws • Visualizzare tutti i cognomi dei clienti che hanno effettuato almeno un acquisto 14 Operatore IN - Esempio http://smartlab.ws • Visualizzare il cognome dei clienti che hanno acquistato almeno un prodotto il cui nome contiene la stringa ‘PR’ 15 Operatore IN - Esempio http://smartlab.ws • Visualizzare il cognome dei clienti che hanno acquistato almeno un prodotto il cui nome contiene la stringa ‘PR’ • Scomposizione in sotto-problemi: • Identificare la lista degli ID di prodotti contenenti la stringa ‘PR’ • Identificare i codici fiscali dei clienti che hanno acquistato almeno un prodotto selezionato allo step precedente • Risalire al cognome dei clienti aventi i codici fiscali identificati al passo precedente 16 Operatore IN - Esempio http://smartlab.ws 17 Operatore IN - Esempio http://smartlab.ws 1 2 3 18 Operatore IN - Esempio http://smartlab.ws • Visualizzare il cognome dei clienti che hanno acquistato almeno un prodotto il cui nome contiene la stringa ‘PR’ • La formulazione sfruttante i join è più snella in questo caso... 19 Operazione preliminare... http://smartlab.ws • Ci servirà a breve per comprendere meglio alcune cose.. • Aggiungiamo un’ulteriore entry alla tabella delle vendite, in particolare un acquisto da parte di Mario Rossi del prodotto avente codice 95 (2 unità) • INSERT INTO vendite VALUES (‘VEN02’,‘ABCDEF12A34B567C’,95,2); 20 Operatore NOT IN http://smartlab.ws • Vogliamo escludere dal set di dati incluso nel nostro DB alcune entry che soddisfano una determinata condizione • In questo caso è utile sfruttare la clausola NOT IN, il duale della clausola IN analizzata in precedenza • Mentre molte (sebbene non tutte) le query sfruttanti l’IN possono anche essere espresse mediante join, non vale altrettanto per il NOT IN • In questo caso, una formulazione con join è molto raramente identificabile o sarebbe complessa da scrivere 21 NOT IN - Esempio http://smartlab.ws • Vogliamo trovare l’elenco dei cognomi dei clienti che non hanno mai acquistato il prodotto avente codice 110 • È possibile utilizzare il join? 22 NOT IN - Esempio http://smartlab.ws • Vogliamo trovare l’elenco dei cognomi dei clienti che non hanno mai acquistato il prodotto avente codice 110 • È possibile utilizzare il join? Questa query è ERRATA ! 23 NOT IN - Esempio http://smartlab.ws • Vogliamo trovare l’elenco dei cognomi dei clienti che non hanno mai acquistato il prodotto avente codice 110 • È possibile utilizzare il join? • La query è errata per due motivi: • L’inner join consente di ottenere solo i cognomi dei clienti che hanno effettuato almeno un acquisto (problema sanabile con la outer join) • In questo modo, troviamo l’elenco dei clienti che hanno acquistato almeno un prodotto diverso dal 110 24 NOT IN - Esempio http://smartlab.ws • Vogliamo trovare l’elenco dei cognomi dei clienti che non hanno mai acquistato il prodotto avente codice 110 25 Costruttore di entry http://smartlab.ws • Permette la definizione temporanea di una entry, elencandone i campi che ne fanno parte tra ( ) • (campo1, campo2, ... ) • Permette di estendere il potere di espressione delle clausole IN e NOT IN 26 Costruttore di entry - Esempio http://smartlab.ws • Sono rari i casi in cui sia utile un costruttore di entry... • Potremmo dover cercare le coppie cognome-nome di tutte le persone nate nel 1956 • Chiaramente, si tratta di un esempio fittizio, si può fare in modo molto più “furbo”... 27 Operatore EXISTS http://smartlab.ws • L’operatore EXISTS svolge un ruolo importante per selezionare i dati da una tabella per cui sono rispettate determinate condizioni di esistenza riferite a dati di altre tabelle • Come già per l’IN, l’EXISTS è spesso sostituibile con un join • Dato che l’EXISTS mette in qualche modo in relazione dati afferenti a due tabelle diverse, l’EXISTS conterrà, nella sua interrogazione nidificata, una clausola di correlazione con la tabella principale dalla quale estrarre i campi da visualizzare 28 EXISTS - Esempio http://smartlab.ws • Trovare i cognomi dei clienti per i quali esiste un acquisto del prodotto 110 29 EXISTS - Esempio http://smartlab.ws • Trovare i cognomi dei clienti per i quali esiste un acquisto del prodotto 110 30 EXISTS - Esempio http://smartlab.ws • Trovare i cognomi dei clienti per i quali esiste un acquisto del prodotto 110 Di solito, vengono inclusi tutti i campi (intanto non vengono selezionati né visualizzati) 31 EXISTS - Esempio http://smartlab.ws • Trovare i cognomi dei clienti per i quali esiste un acquisto del prodotto 110 clausola di correlazione 32 EXISTS - Esempio http://smartlab.ws • Trovare i cognomi dei clienti per i quali esiste un acquisto del prodotto 110 clausola di selezione 33 EXISTS http://smartlab.ws • Il predicato della clausola EXISTS è: • Vero se l’interrogazione interna restituisce almeno una tupla • Falso, altrimenti • Una query nidificata può fare riferimento a campi di tabelle definite in interrogazioni più esterne, mentre non può fare riferimento a campi di tabelle di query allo stesso livello o più interne • Nell’esempio precedente, nella prima SELECT, il campo Cognome non poteva che essere della tabella anagrafica, mentre la query nidificata poteva fare riferimento a campi della tabella vendite e della tabella anagrafica 34 NOT EXISTS http://smartlab.ws • La clausola EXISTS ha il suo duale, il NOT EXISTS, il cui predicato è vero solo se la nested query restituisce l’insieme vuoto • Esempio: trovare tutti i clienti che non hanno mai comprato il prodotto 110 35 Interrogazioni correlate http://smartlab.ws • L’utilizzo della clausola EXISTS ha introdotto un concetto nuovo: la clausola di correlazione fra tabelle poste in interrogazioni differenti e nidificate • Talvolta è utile correlare due interrogazioni nidificate al fine di estrarre informazioni di più alto livello • Un esempio sono valori aggregati con campi non aggregati e descriventi meglio le caratteristiche dell’aggregato stesso • Le clausole di correlazione compaiono sempre nel WHERE • Possono far riferimento a campi di tabelle citate in query nidificate più esterne ma mai più interne 36 Interrogazioni correlate - Esempio http://smartlab.ws • Supponendo che prodotti con nomi uguali siano uguali, trovare per ogni prodotto il costo unitario massimo. Visualizzare il costo e l’ID del prodotto 37 Interrogazioni correlate - Esempio http://smartlab.ws • Supponendo che prodotti con nomi uguali siano uguali, trovare per ogni prodotto il costo unitario massimo. Visualizzare il costo e l’ID del prodotto • Dobbiamo pertanto: • Analizzare tutti i prodotti presenti nel DB per nome • Cercare il prodotto dal costo unitario massimo 38 Interrogazioni correlate - Esempio http://smartlab.ws • Supponendo che prodotti con nomi uguali siano uguali, trovare per ogni prodotto il costo unitario massimo. Visualizzare il costo e l’ID del prodotto 39 Operazione di divisione http://smartlab.ws • Viene definita l’operazione di divisione come un’operazione necessaria al fine di identificare tutti le entry di una tabella che soddisfano una relazione nidificata su tutte le entry di un’altra tabella 40 Operazione di divisione - Esempio http://smartlab.ws • Propedeuticamente, aggiungiamo ancora due entry alla tabella vendite 41 Operazione di divisione - Esempio http://smartlab.ws • Vogliamo identificare il codice fiscale dei clienti che hanno comprato tutti i prodotti presenti nel listino • Sostanzialmente controlliamo che la somma dei prodotti diversi per cliente sia pari al numero totale di prodotti in listino 42 Operazione di divisione - Esempio http://smartlab.ws • Possiamo ovviamente pensare anche a query più complesse con dei join, per esempio se volessimo visualizzare in output il cognome del cliente in aggiunta al suo CF 43 Table functions http://smartlab.ws • Le table function sono utili per definire tabelle temporanee da utilizzare per operazioni di calcolo complesse (es. doppie aggregazioni) • Le table functions • hanno la struttura di una query tradizionale (lo sono, a tutti gli effetti) • è definita in una FROM • può essere referenziata come una normale tabella mediante un alias • Le table functions permettono, in molti casi, di formulare in modo equivalente le interrogazioni correlate • Spesso usare una table function risulta più intuitivo 44 Interrogazioni correlate e table functions http://smartlab.ws • Supponendo che prodotti con nomi uguali siano uguali, trovare per ogni prodotto il costo unitario massimo. Visualizzare il costo e l’ID del prodotto 45 Interrogazioni correlate e table functions http://smartlab.ws • Supponendo che prodotti con nomi uguali siano uguali, trovare per ogni prodotto il costo unitario massimo. Visualizzare il costo e l’ID del prodotto 46 Table functions - Esempio http://smartlab.ws • Supponendo che prodotti con nome uguale siano lo stesso prodotto, trovare il prodotto caratterizzato dal costo unitario medio massimo 47 Nested query per DELETE e UPDATE http://smartlab.ws • Le interrogazioni nidificate possono essere utilizzate nei costrutti DELETE e UPDATE per fornire maggiori funzionalità all’utente • Entrambi i costrutti includono una clausola WHERE • Essa può includere condizioni molto semplici (come visto nelle precedenti lezioni) • Oppure può includere una query nidificata 48 Nested query per DELETE e UPDATE - Esempio http://smartlab.ws • Nella tabella vendite, aggiornare tutte le entry per il cliente “Paperino Pippo” settando la quantità di venduto a 5 e l’ID del prodotto a 110 49 Nested query per DELETE e UPDATE - Esempio http://smartlab.ws • Nella tabella vendite, eliminare tutte le entry per il cliente “Paperino Pippo” 50