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