SQL 3. 1 CSE2132 Database Systems Week 3 Lecture SQL Data Manipulation.
SQL come Data Manipulation Language Funzioni Aggregate e … · 2003-12-03 · SQL © Matteo...
Transcript of SQL come Data Manipulation Language Funzioni Aggregate e … · 2003-12-03 · SQL © Matteo...
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
SQL
SQL come Data Manipulation Language-
Funzioni Aggregate e GROUP BY
2
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Persone8775Luisa3585Sergio
3550Anna3026Filippo4050Luigi2060Franco4130Olga
4255Maria1525Aldo2127AndreaRedditoEtaNome
Maternita
FilippoAnnaAndreaMariaAldoMaria
OlgaAnnaLuigiLuisaMariaLuisaFiglioMadre
Paternita
AndreaFrancoAldoFranco
FilippoLuigiOlgaLuigiFrancoSergioFiglioPadre
Esempio DB 1
3
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Impiegato
4516DistribuzioneNeriFranco8014DirezioneRossiCarlo737DirezioneLanziLorenzo4075AmministrazioneBorroniPaola4620ProduzioneFrancoMarco
4020AmministrazioneVerdiGiuseppe3620ProduzioneBianchiCarlo4510AmministrazioneRossiMarioStipendioUfficioDipartCognomeNome
MilanoVia Tito LivioDirezioneMilanoVia MoroneRicerca
RomaVia SegreDistribuzioneTorinoPiazza LavaterProduzioneMilanoVia Tito LivioAmministrazioneCittaIndirizzoNome
Dipartimento
Esempio DB 2
4
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Necessità di operatori su tuple
• Nelle interrogazioni viste finora le condizioni di selezione (Clausola Where) venivano valutate suciascuna tupla indipendentemente da tutte le altre.
• Questo e’ lo stesso comportamento dell’algebra relazionale.
• Si puo’ ad esempio verificare se un impiegato recepisce un certo stipendio. Ma non si puo’ contare il numero di impiegati di un certo dipartimento, perche’ occorrerebbe poter manipolare un insieme di tuple.
• A questo scopo SQL mette a disposizione glioperatori aggregati.
5
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Esempio di operatore aggregato: count
select count(*) AS numeroImpiegatifrom Impiegatowhere Dipart = ‘Produzione’
2numeroImpiegati
6
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Valutazione di operatore aggregato (1)
• Quando si utilizzano operatori aggregati, prima si valuta la query senza operatore.
select *from Impiegatowhere Dipart = ‘Produzione’
4620ProduzioneFrancoMarco3620ProduzioneBianchiCarloStipendioUfficioDipartCognomeNome
7
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Valutazione di operatore aggregato (2)
• Poi si considerano le tuple come un insieme.select count(*) AS numeroImpiegatifrom Impiegatowhere Dipart = ‘Produzione’
4620ProduzioneFrancoMarco3620ProduzioneBianchiCarloStipendioUfficioDipartCognomeNome
8
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
COUNT
• COUNT puo’ anche riferirsi a singoli attributi (il motivo sara’ piu’ chiaro tra poco).
select count(*) AS numeroImpiegatifrom Impiegato
select count(Stipendio) AS numeroStipendifrom Impiegato
8numeroImpiegati
8numeroStipendi
9
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
COUNT
• Si valuta esattamente allo stesso modo.select count(Stipendio) AS numeroStipendifrom Impiegato
4580734046
403645Stipendio
10
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
COUNT
• Se si vogliono considerare solo i valori distinti, si puo’ utilizzare l’opzione distinct.
select count(Stipendio) AS numeroStipendifrom Impiegato
select count(distinct Stipendio) AS StipDiversifrom Impiegato
8numeroStipendi
6StipDiversi
11
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
COUNT
• Questo equivale alla valutazione della query con l’opzione distinct, per poi applicare come al solito l’operatore aggregato.
select distinct Stipendiofrom Impiegato
807346
403645Stipendio
12
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
COUNT e valori nulli
• Attenzione ai valori nulli quando si specificano gli attributi su cui contare le righe.
4516DistribuzioneNeriFranco8014DirezioneRossiCarlonull7DirezioneLanziLorenzonull75AmministrazioneBorroniPaolanull20ProduzioneFrancoMarco
4020AmministrazioneVerdiGiuseppe3620ProduzioneBianchiCarlo4510AmministrazioneRossiMarioStipendioUfficioDipartCognomeNome
ImpiegatoConNulli
13
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
COUNT e valori nulli
select count(*) AS numeroImpiegatifrom ImpiegatoConNulli
select count(Stipendio) AS numeroStipendifrom ImpiegatoConNulli
8numeroImpiegati
5numeroStipendi
14
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Altri operatori
• Quanto detto per COUNT vale ancheper gli operatori: sum, max, min, avg.
• Questi operatori escludono opportunamente i valori nulli.
• L’opzione distinct puo’ ancora essere utilizzata.
• Altri operatori esistono (varianza, mediano...), ma non sono standard. Controllare il manuale del sistema che si vuole utilizzare.
15
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Altri operatori
select max(Stipendio) AS stipendioMaxfrom Impiegato
select min(Stipendio) AS stipendioMinfrom Impiegato
80stipendioMax
36stipendioMin
16
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Altri operatori
select sum(Stipendio) AS sommaStipendifrom Impiegato
select avg(Stipendio) AS mediaStipendifrom Impiegato
405sommaStipendi
50.625mediaStipendi
17
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e Join
• Gli operatori aggregati si possono utilizzare anche in concomitanza con i join.
select max(Stipendio) AS stipendioMassimofrom Impiegato, Dipartimento Dwhere Dipart = D.Nome AND Citta = “Milano”
80stipendioMassimo
18
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e ridenominazione
• Se non utilizziamo la AS, il risultato non ha nome.
select max(Stipendio)from Impiegato, Dipartimento Dwhere Dipart = D.Nome AND Citta = “Milano”
80
19
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e target list
• ATTENZIONE. Quando si utilizza un operatore aggregato consideriamo insiemi di tuple. La seguente query e’ scorretta.
select Cognome, Nome, min(Stipendio)from Impiegatowhere Dipart = ‘Amministrazione’
4075AmministrazioneBorroniPaola4020AmministrazioneVerdiGiuseppe4510AmministrazioneRossiMarioStipendioUfficioDipartCognomeNome
20
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Interrogazioni con raggruppamento
• Gli operatori aggregati vengono applicati ad un insieme di righe.
• Gli esempi visti operano su tutte le righe.• Spesso esiste l’esigenza di applicare
operatori aggregati distintamente ad insiemi di tuple.
• Ad esempio: per ogni dipartimento, trovare la somma degli stipendi.
21
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e raggruppamenti
“Per ogni dipartimento, la somma degli stipendi”Selezioniamo il dipartimento e gli stipendi.
45Distribuzione80Direzione73Direzione40Amministrazione46Produzione
40Amministrazione36Produzione45AmministrazioneStipendioDipart
22
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e raggruppamenti
“Per ogni dipartimento, la somma degli stipendi”Raggruppiamo per dipartimento.
46Produzione
40Amministrazione40Amministrazione
45Distribuzione80Direzione73Direzione
36Produzione
45AmministrazioneStipendioDipart
23
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e raggruppamenti
“Per ogni dipartimento, la somma degli stipendi”Calcoliamo la somma.
DirezioneDistribuzioneProduzione
AmministrazioneDipart
12582
15345
24
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e raggruppamenti
“Per ogni dipartimento, la somma degli stipendi”select Dipart, sum(Stipendio) AS TotaleStipendifrom ImpiegatoGROUP BY Dipart
DirezioneDistribuzioneProduzione
AmministrazioneDipart
12582
15345
TotaleStipendi
25
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Passo a passo
“Per ogni dipartimento, la somma degli stipendi”select Dipart, Stipendiofrom Impiegato
45Distribuzione80Direzione73Direzione40Amministrazione46Produzione
40Amministrazione36Produzione45AmministrazioneStipendioDipart
26
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Passo a passo
“Per ogni dipartimento, la somma degli stipendi”select Dipart, Stipendiofrom ImpiegatoGroup By Dipart
46Produzione
40Amministrazione40Amministrazione
45Distribuzione80Direzione73Direzione
36Produzione
45AmministrazioneStipendioDipart
27
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Passo a passo
“Per ogni dipartimento, la somma degli stipendi”select Dipart, sum(Stipendio) As TotaleStipendifrom ImpiegatoGroup By Dipart
DirezioneDistribuzioneProduzione
AmministrazioneDipart
12582
15345
TotaleStipendi
28
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e target list
• ATTENZIONE: nel momento in cui si utilizzano funzioni aggregate, si stanno considerando insiemi di tuple, non singole tuple.
• Di conseguenza, non e’ possibile utilizzare nella target list attributi non utilizzati per il raggruppamento.
• Infatti, questi attributi possono presentare piu’ valori per ogni insieme di tuple. Non e’ quindi possibile ottenere un singolo valore per ogni gruppo di tuple.
29
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e target list
• Ad esempio, la seguente interrogazione NON HA SENSO:
select Cognome, Dipart, sum(Stipendio)from ImpiegatoGroup By Dipart
Cognome
Direzione
Distribuzione
Produzione
Amministrazione
Dipart
125
82
153
45
Rossi VerdiBorron
BianchiFranco
Rossi Lanzi
Neri
Quale cognomebisogna scegliere?
30
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e target list
• Le interrogazioni che abbiamo visto precedentemente, con funzioni aggregate e senza Group By, possono essere pensate come query in cui il Group By ha prodotto un solo insieme.
• Continua dunque a valere la regola di non utilizzare attributi nella target list non usati per il raggruppamento.
• Poiche’ in assenza del Group By nessun attributo viene utilizzato per il raggruppamento, se si utilizzano funzioni aggregate non si possono specificare altri attributi nella target list.
31
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e target list
• Query corretta:select min(Stipendio), max(Stipendio)from Impiegato• Query NON corretta:select Cognome, max(Stipendio)from Impiegato
32
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e target list
• Questa limitazione puo’ talvolta sembrare eccessiva.
• Ad esempio, la seguente ragionevolequery NON e’ corretta:
select Dipart, count(*), Cittafrom Impiegato I Join Dipartimento D
on I.Dipart = D.Nomegroup by Dipart
33
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatori aggregati e target list
• Il problema e’ facilmente risolto raggruppando su tutti gli attributi utilizzati direttamente nella target list.
select Dipart, count(*), Cittafrom Impiegato I Join Dipartimento D
on I.Dipart = D.Nomegroup by Dipart, Citta
34
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Condizioni sui gruppi
• Ovviamente, anche utilizzando GROUP BY e’ possibile filtrare le tuple sulla base di predicati.
• Ad esempio:select min(Stipendio), max(Stipendio)from Impiegatowhere Ufficio = 20group by Dipart
35
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Condizioni sui gruppi
• Se le condizioni sono da calcolare sui raggruppamenti di tuple, si utilizza la clausola HAVING.
• Cio’ accade quando le condizioni utilizzano funzioni aggregate.
select Dipart, sum(Stipendio)from Impiegatogroup by DipartHAVING sum(Stipendio) > 100
DirezioneAmministrazioneDipart
125153
36
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Where o Having?
•Per decidere se specificare le condizioni nella clausola Where o tramite Having la regola semplice: – Se bisogna utilizzare una funzioneaggregata, significa che la condizione concerne gli insiemi di tuple: Having.– In caso contrario: Where.
37
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Where o Having?
“I dipartimenti per cui la media degli stipendi degli impiegati che lavorano nell'ufficio 20 è superiore a 25 milioni”select Dipartfrom Impiegatowhere Ufficio = 20group by Diparthaving avg(Stipendio) > 25
38
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Riassumiamo
SelectSQL ::=select ListaAttributiOEspressionifrom ListaTabelle[ where CondizioniSemplici ][ group by ListaAttributiDiRaggruppamento ][ having CondizioniAggregate ][ order by ListaAttributiDiOrdinamento ]
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
SQL
SQL come Data Manipulation Language-
Operatori insiemistici
40
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Necessita’ di operatori insiemistici
• Assumiamo di volere elencare in una tabella i nomi dei padri e delle madri.
• Non siamo in grado di farlo utilizzando quanto imparato finora.
AnnaMariaMaria
AnnaLuisaLuisaMadre
FrancoFranco
LuigiLuigiSergioPadre
41
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Necessita’ di operatori insiemistici
• Abbiamo bisogno di un operatore di unione, che possa produrre come risultato una tabella in cui sono elencate le righe ottenute da piu’ Select.
AnnaMariaMaria
AnnaLuisaLuisaMadre
FrancoFranco
LuigiLuigiSergioPadre
42
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Unione
SELECT PadreFROM PaternitaUNIONSELECT MadreFROM Maternita
MariaAnna
FrancoLuisa
LuigiSergioPadre
43
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Unione: considerazioni
SELECT PadreFROM PaternitaUNIONSELECT MadreFROM Maternita
MariaAnna
FrancoLuisa
LuigiSergioPadre
Gli operatori insiemisticieliminano i duplicati.
44
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Unione: considerazioni
SELECT PadreFROM PaternitaUNION ALLSELECT MadreFROM Maternita
Franco
MariaMariaAnnaAnnaLuisa
FrancoLuisa
LuigiLuigiSergioPadre
L’opzione ALL li mantiene.
45
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Unione: considerazioni
SELECT PadreFROM PaternitaUNIONSELECT MadreFROM Maternita
MariaAnna
FrancoLuisa
LuigiSergioPadre
Il nome utilizzato e’ tipicamente quello del primo select (si potrebbe decidere di non
utilizzare alcun nome)
46
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Notazione Posizionale
select Padre, Figliofrom Paternitaunionselect Madre, Figliofrom Maternita
MariaMariaAnnaAnnaLuisaLuisaMadre
AldoAndreaFilippoOlgaLuigiMariaFiglio
AndreaFrancoAldoFranco
FilippoLuigiOlgaLuigiFrancoSergioFiglioPadre
47
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Notazione Posizionale
select Padre, Figliofrom Paternitaunionselect Figlio, Madrefrom Maternita
AldoAndreaFilippoOlgaLuigiMariaFiglio
AnnaMariaMaria
AnnaLuisaLuisaMadre
AndreaFrancoAldoFranco
FilippoLuigiOlgaLuigiFrancoSergioFiglioPadre
48
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Notazione Posizionale
• Anche con le ridenominazione non cambia nulla: e’ sempre l’ordine a contare.
select Padre AS genitore, Figliofrom Paternitaunionselect Figlio, Madre AS genitorefrom Maternita
49
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Intersezione
• L’intersezione e’ analoga:select Nomefrom Impiegatointersectselect Cognomefrom Impiegato• Otteniamo:
FrancoCarloLorenzoPaolaMarco
GiuseppeCarloMarioNome
FrancoBorroniLanziRossiNeriVerdiBianchiRossiCognome
FrancoNome
50
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Intersezione
A differenza dell’unione, questa query e’ esprimibile senza utilizzare esplicitamente l’operatore insiemistico:select I1.Nomefrom Impiegato I1, Impiegato I2where I1.Nome = I2.Cognome
51
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Differenza
• Idem per la differenza:select Nomefrom Impiegatoexceptselect Cognomefrom Impiegato• Otteniamo: Carlo
LorenzoPaolaMarco
GiuseppeCarloMarioNome
52
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Differenza
•Anche questa query e’ esprimibile senza utilizzare esplicitamente l’operatore insiemistico.•Occorre pero’ utilizzare una struttura piu’ complessa, composta da due Select annidati.•Nella prossima sezione vedremo come scrivere questo tipo di query.
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
SQL
SQL come Data Manipulation Language-
Interrogazioni nidificate
54
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Interrogazioni nidificate
• Abbiamo in precedenza mostrato come la seguente interrogazione sia errata:
select Cognome, max(Stipendio)from Impiegato• L’intento e’ quello di selezionare il cognome
dell’impiegato/i che guadagna di piu’, con il proprio stipendio.
• Questo e’ facilmente realizzabile tramite due query.
55
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Interrogazioni nidificate
• Prima troviamo lo stipendio massimo:select Cognomefrom Impiegatowhere Stipendio = (select max(Stipendio)
from Impiegato)
80
56
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Interrogazioni nidificate
• Poi cerchiamo gli impiegati il cui stipendio e’ uguale al massimo:
select Cognomefrom Impiegatowhere Stipendio = (select max(Stipendio)
from Impiegato)
57
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Interrogazioni nidificate: un altro esempio
• “Nome e reddito del padre di Mario”select Nome, Redditofrom Personewhere Nome = (select Padre
from Paternitawhere Figlio = 'Mario')
Padre di Mario
58
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Interrogazioni nidificate: un altro esempio
• “Nome e reddito del padre di Mario”select Nome, Redditofrom Personewhere Nome = (select Padre
from Paternitawhere Figlio = 'Mario')
59
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Interrogazioni nidificate: un altro esempio
• Una soluzione alternativa, senza nidificazione, e’ la seguente:
select Nome, Redditofrom Persone, Paternitawhere Nome = Padre and
Figlio = 'Mario'
60
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
any/all
• Negli esempi precedenti era chiaro che il risultato del blocco piu’ interno avrebbe restituito un’unica tupla.
• In generale, non e’ cosi’. Si deve confrontare un attributo con un insieme di tuple.
• Vengono quindi utilizzati operatori insiemistici esistenziali: any e all.
61
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
any/all
• “Gli impiegati che lavorano in dipartimenti di Roma”
• Cioe’: “che lavorano in almeno uno dei dipartimenti di Roma.
select *from Impiegatowhere Dipart = any (select Nome
from Dipartimentowhere Citta = 'Roma')
62
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
any/all
• “I dipartimenti in cui non lavorano impiegati di cognome Rossi”
• Cioe’: “diverso da tutti i dipartimenti in cui lavora un Rossi.
select *from Dipartimentowhere Nome <>all (select Dipart
from Impiegato where Cognome = ‘Rossi’)
63
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
any/all
• In generale,• where Attributo θ all (select ...)• E’ vero quando Attributo soddisfa la
relazione θ (<,<=,>,>=,=,<>) con tutte le tuple resituite da (select ...).
• where Attributo θ any (select ...)• E’ vero quando Attributo soddisfa la
relazione θ con almeno una delle tuple.
64
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
any/all
• ESERCIZIO: Esprimere le ultime due interrogazioni senza utilizzare la nidificazione.
65
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
in / not in
• SQL mette a disposizione anche gli operatori in, e not in, che sono equivalenti a =any e <>all.
select *from Impiegatowhere Dipart in (select Nome
from Dipartimentowhere Citta = 'Roma')
select *from Dipartimentowhere Nome not in (select Dipart
from Impiegato where Cognome = ‘Rossi’)
66
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Interrogazioni nidificate, commenti
• La prima versione di SQL prevedeva solo la forma nidificata (o strutturata), con una sola relazione in ogni clausola FROM. Il che è insoddisfacente:– La dichiaratività è limitata.– Non si possono includere nella target list attributi di relazioni
nei blocchi interni.• La forma nidificata è “meno dichiarativa”, ma talvolta
più leggibile (richiede meno variabili).• La forma piana e quella nidificata possono essere
combinate.• Le sottointerrogazioni non possono contenere
operatori insiemistici (“l’unione si fa solo al livello esterno”). La limitazione non è significativa.
67
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Interrogazioni piatte o nidificate?
• Spesso ad una query nidificata necorrisponde una piatta.
• La scelta deve essere guidata in primis dalla leggibilita’, in quanto sara’ poi il sistema a scegliere un piano di esecuzione efficiente.
68
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Interrogazioni piatte o nidificate?
• “Nome e reddito dei padri di persone che guadagnano più di 20 milioni"
select Nome, Redditofrom Personewhere Nome in (select Padre
from Paternitawhere Figlio =any (select Nome
from Personewhere Reddito > 20))
select distinct P.Nome, P.Redditofrom Persone P, Paternita, Persone Fwhere P.Nome = Padre and
Figlio = F.Nome andF.Reddito > 20
69
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Interrogazioni piatte o nidificate?
• “Nome degli impiegati che si chiamano come un impiegato di Produzione"select I1.Nomefrom Impiegato I1, Impiegato I2where I1.Nome = I2.Nome andI2.Dipart = 'Produzione'
select Nomefrom Impiegatowhere Nome = any (select Nome
from Impiegatowhere Dipart = 'Produzione')
70
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatore exists
• Un ulteriore operatore insiemistico e’ exists.• Si puo’ utilizzare per verificare se il risultato di
una query interna e’ vuoto.
71
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatore exists
• “Le persone che hanno almeno un figlio”select *from Personewhere exists (select *
from Paternitawhere Padre = Nome) or
exists (select *from Maternitawhere Madre = Nome)
72
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatore exists
• Le persone che hanno almeno un figlioselect *from Personewhere exists (select *
from Paternitawhere Padre = Nome) or
exists (select *from Maternitawhere Madre = Nome)
LuisaSergio
AnnaFilippoLuigiFrancoOlga
MariaAldoAndreaNome
AnnaMariaMaria
AnnaLuisaLuisaMadre
FrancoFranco
LuigiLuigiSergioPadre
73
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatore exists
• Le persone che hanno almeno un figlioselect *from Personewhere exists (select *
from Paternitawhere Padre = Nome) or
exists (select *from Maternitawhere Madre = Nome)
LuisaSergio
AnnaFilippoLuigiFrancoOlga
MariaAldoAndreaNome
AnnaMariaMaria
AnnaLuisaLuisaMadre
FrancoFranco
LuigiLuigiSergioPadre
74
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatore exists
• Le persone che hanno almeno un figlioselect *from Personewhere exists (select *
from Paternitawhere Padre = Nome) or
exists (select *from Maternitawhere Madre = Nome)
LuisaSergio
AnnaFilippoLuigiFrancoOlga
MariaAldoAndreaNome
AnnaMariaMaria
AnnaLuisaLuisaMadre
FrancoFranco
LuigiLuigiSergioPadre
75
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Operatore exists
• Le persone che hanno almeno un figlioselect *from Personewhere exists (select *
from Paternitawhere Padre = Nome) or
exists (select *from Maternitawhere Madre = Nome)
LuisaSergio
AnnaFilippoLuigiFrancoOlga
MariaAldoAndreaNome
AnnaMariaMaria
AnnaLuisaLuisaMadre
FrancoFranco
LuigiLuigiSergioPadre
76
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Semantica delle espressioni “correlate”
• L’interrogazione interna viene eseguita una volta per ciascuna ennupla dell’interrogazione esterna.
select Attributofrom Tabellawhere exists (select *
from Paternitawhere Padre = Nome)
SelectFrom ...Where Attributo ...
77
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Esempio di utilizzo di exists
• “Trovare i padri i cui figli guadagnano tutti più di venti milioni"
select distinct Padrefrom Paternita Zwhere not exists (select *
from Paternita W, Personewhere W.Padre = Z.Padre andW.Figlio = Nome andReddito <= 20)
78
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
exists per specificare una differenza
select Nomefrom Impiegatoexceptselect Cognome as Nomefrom Impiegato
select Nomefrom Impiegato Iwhere not exists (select *
from Impiegatowhere Cognome = I.Nome)
79
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
exists per specificare un’unione
select *from Personewhere Reddito > 30unionselect F.*from Persone F, Paternita, Persone Pwhere F.Nome = Figlio and
Padre = P.Nome andP.Reddito > 30
select *from Persone Fwhere Reddito > 30 or
exists (select *from Paternita, Persone Pwhere F.Nome = Figlio and
Padre = P.Nome andP.Reddito > 30)
80
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Visibilità
• Regole di visibilità:– Non è possibile fare riferimenti a variabili definite
in blocchi più interni– Se un nome di variabile è omesso, si assume
riferimento alla variabile più “vicina”• Nota: in un blocco si può fare riferimento a
variabili definite in blocchi più esterni.• L’interrogazione interna va ripetuta una volta
per ciascun valore della variabile.
81
SQL© Matteo Magnani, Danilo Montesi – Università di Bologna
Visibilità
• La seguente query e’ scorretta, in quanto D1 e’ visibile solo nel blocco in cui e’ dichiarata:select *from Impiegatowhere Dipart in (select Nome
from Dipartimento D1where Nome = 'Produzione') or
Dipart in (select Nomefrom Dipartimento D2where D2.Citta = D1.Citta)
Visibilita’ di D1