SQL come Data Manipulation Language Funzioni Aggregate e … · 2003-12-03 · SQL © Matteo...

Post on 26-Jul-2020

1 views 0 download

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