SQL (II)
Interrogazioni (parte 2)
Notazione
Le parentesi angolari <,>: permettono
di isolare un termine della sintassi
Le parentesi quadre [,]: indicano che il
termine all’interno è opzionale

Può non comparire o comparire una sola
volta
2
Notazione
Le parentesi graffe {,}: indicano che il
termine racchiuso può non comparire o
essere ripetuto un numero arbitrario di
volte
Le barre verticali |: indicano che deve
essere scelto uno tra i termini separati
dalle barre
3
Interpretazione algebrica delle
interrogazioni SQL
select T1.Attrib_11,…,Th.Attrib_hm
from Tabella1 as T1,…,Tabellan as Tn
where condizione
T1.Attrib_11,…,Th.Attrib_hm(
condizione(Tabella1 x … x Tabellan))
Per semplicità, omettiamo le ridenominazioni che ci permettono
di considerare tutti i join come prodotto cartesiano
4
Algebra->calcolo, SQL->linguaggio
SQL gestisce i duplicati (select e select
distinct), algebra no (basata su insiemi)
select *
from Impiegati
ordered by [asc|desc] Matricola
Operatori aggregati
Interrogazioni nidificate
per
ordinare
le tuple
5
Tabella “Impiegato”
Impiegato
Nome
Cognome Dipart
Ufficio Stipendio Città
Mario
Rossi
Amministr 10
15
Milano
Carlo
Bianchi
Prod
20
12
Torino
Giuseppe Verdi
Amministr 20
13
Roma
Franco
Neri
Distrib
16
15
Napoli
Carlo
Rossi
Direzione
14
27
Milano
Lorenzo
Lanzi
Direzione
7
21
Genova
Paola
Burroni
Ammistr
75
13
Venezia
Marco
Franco
Prod
20
14
Roma
6
Tabella “Dipartimento”
Dipartimento
Nome
Indirizzo
Città
Amministr Via Tito Livio
27
Milan
o
Prod
P.le Lavater 3
Torino
Distrib
Via Segre 9
Roma
Direzione
Via Tito Livio
27
Milan
o
Ricerca
Via Morone 6
Milan
o
7
Operatori aggregati
Algebra relazionale: tutte le condizioni
sono valutate su una tupla alla volta, in
modo indipendente
SQL offre degli operatori che lavorano
su più di una tupla alla volta:
count,sum,max,min,avg
8
Interrogazione 12
select count(*)
from Impiegato
where Dipart = ‘Prod’
count(<*|[distinct|all]ListaAttributi>)
valori diversi tra
loro
non null
9
Interrogazioni 13, 14
Gli operatori aggregati si applicano sulle tuple selezionate
dalla clausola “where” (se c’è)
count(<*|[distinct|all]ListaAttributi>)
Numero di stipendi diversi
select count(distinct Stipendio)
from Impiegato
Numero di righe che hanno nome non nullo
select count(all Nome)
from Impiegato
10
sum, max, min, avg
Prendono solo espressioni
rappresentanti valori numerici o
intervalli di tempo
distinct e all stesso significato di
prima
Altri operatori a seconda delle versioni
di SQL (solitamente operatori statistici)
11
Interrogazioni 15, 16
Somma stipendi di Amministrazione
select sum(Stipendio)
from Impiegato
where Dipart = ‘Amministr’
Stipendi min, max, medio degli Impiegati
select
min(Stipendio),max(Stipendio),avg(Stipendio)
from Impiegato
12
Interrogazione 17
Max stipendio tra impiegati che lavorano in dip
a Milano
select max(Stipendio)
from Impiegato, Dipartimento
where Dipart = NomeDip and
Citta = ‘Milano’
Equijoin
13
Interrogazione non corretta
select Cognome, Nome, max(Stipendio)
from Impiegato, Dipartimento
where Dipart = NomeDip and
Citta = ‘Milano’
Perché è scorretta?
Ha senso con group by…
14
Interrogazione 18
Estrarre la somma degli stipendi di tutti gli
impiegati dello stesso dipartimento
select Dipart, sum(Stipendio)
from Impiegato
group by Dipart
15
Interrogazione 18 (cont.)
È come se prima si facesse la query
select Dipart, Stipendio
from Impiegato
ottenendo la tabella…
16
Interrogazione 18 (cont.)
Dipart
Amministrazione
Produzione
Amministrazione
Stipendio
22.500
18.000
20.000
Distribuzione
Direzione
Direzione
22.500
40.000
36.500
Amministrazione
Produzione
20.000
23.000
17
Interrogazione 18 (cont.)
Poi le tuple si raggruppano in sottoinsiemi in
base allo stesso valore dell’attributo Dipart
Dipart
Stipendio
Amministrazione
22.500
Amministrazione
20.000
Amministrazione
20.000
Produzione
18.000
Produzione
23.000
Distribuzione
22.500
Direzione
40.000
Direzione
36.500
18
Interrogazione 18 (cont.)
Poi le tuple si raggruppano in sottoinsiemi in
base allo stesso valore dell’attributo Dipart
Dipart
Stipendio
Amministrazione
22.500
Amministrazione
20.000
Amministrazione
20.000
Produzione
18.000
Produzione
23.000
Distribuzione
22.500
Direzione
40.000
Direzione
36.500
19
Interrogazione 18 (cont.)
Infine l’operatore sum viene applicato
separatamente a ogni sottoinsieme
Dipart
sum(Stipendio)
Amministrazione
62.500
Produzione
41.000
Distribuzione
22.500
Direzione
76.500
20
Interrogazione non corretta
select Ufficio
from Impiegato
group by Dipart
Perché?
21
Interrogazione non corretta
select Ufficio
from Impiegato
group by Dipart
• Ogni valore dell’attributo Dipart
corrisponderanno diversi valori dell’attributo Ufficio
• Dopo l’esecuzione del raggruppamento, invece,
ogni sottoinsieme di righe deve corrispondere a
una sola riga nella tabella risultato della
interrogazione
22
Interrogazione 19
Dipartimenti, il numero di impiegati di ciascun dipart,
e la città sede del dipart
select Dipart, count(*), D.citta
from Impiegato I, Dipartimento D
where I.Dipart=D.Nome
group by Dipart
 scorretta!
23
Interrogazione 19
select Dipart, count(*), D.Citta
from Impiegato I, Dipartimento D
where I.Dipart=D.Nome
group by Dipart, D.Citta
 corretta!
24
Predicati sui gruppi
group by: le tuple vengono raggruppate in
sottoinsiemi
Si può voler considerare solo sottoinsiemi che
soddisfano una certa condizione
Sulle singole righe: clausola “where”
Se condizioni di tipo aggregato: clausola
having:ogni sottoinsieme di tuple della
group by viene selezionato se il predicato di
having è soddisfatto
25
Interrogazione 20
Dipartimenti che spendono più di 50 mille in stipendi
select Dipart, sum(Stipendi) as SommaStip
from Impiegato
group by Dipart
having sum(Stipendio) > 50
26
Predicati sui gruppi
Consigli di buon uso

Meglio usare having con group by
 Senza group by: l’intero insieme di righe è trattato
come un unico raggruppamento
 Se la condizione non è soddisfatta il risultato sarà vuoto

Solo predicati in cui ci sono operatori aggregati
nella clausola having
27
Interrogazione 21
Dipartimenti per cui la media degli stipendi degli impiegati
che lavorano nell’ufficio 20 è > di 12.500 mille
select Dipart
from Impiegato
where Ufficio = 20
group by Dipart
having avg(Stipendio) > 12.500
28
Interrogazioni in SQL
La forma sintetica generale di
un’interrogazione SQL diventa:
SelectSQL ::=
select ListaAttributiOEspressioni
from ListaTabelle
[ where CondizioniSemplici ]
[ group by ListaAttributiDiRaggrupamento ]
[ having CondizioniAggregate ]
[ order by ListaAttributiDiOrdinamento ]
29
Interrogazioni di tipo
insiemistico
union (unione), intersect
(intersezione) ed except (differenza)
Assumono come default di eseguire una
eliminazione di duplicati


L’eliminazione dei duplicati rispetta meglio
il tipico significato delle operatori
insiemistici
Per preservare i duplicati: usare l’operatore
con la parola chiave all
30
Interrogazioni di tipo
insiemistico
La sintassi per l’uso degli operatori
insiemistici:
SelectSQL {<union|intersect|except>
[all] SelectSQL }
31
Interrogazioni di tipo
insiemistico
SQL non richiede che gli schemi su cui
vengono effettuate le operazioni insiemistiche
siano identiche



Solo che gli attributi siano in pari numero e che
abbiano domini compatibili
La corrispondenza tra gli attributi non si basa sul
nome ma sulla posizione degli attributi
Se gli attributi hanno nome diverso, il risultato
normalmente usa i nomi del primo operando
32
Interrogazione 22
(insiemistiche)
Nomi e cognomi degli impiegati (notare: non serve
che gli attributi abbiano lo stesso nome, ma solo lo
stesso “tipo”, per esempio stringa)
select Nome
from Impiegato
union
select Cognome
from Impiegato
L’unione
non si
può
simulare
33
Interrogazione 22
(insiemistiche)
select Nome
from Impiegato
union
select Cognome
from Impiegato
Nome
Mario
Carlo
Giuseppe
Franco
Lorenzo
Paola
Marco
Rossi
Bianchi
Verdi
Neri
Lanzi
Borroni
34
Interrogazione 23
(insiemistiche)
Nomi e cognomi degli impiegati mantenendo i duplicati
select Nome
from Impiegato
where Dipart<>’Amministr’
union all
select Cognome
from Impiegato
where Dipart<>’Amministr’
Nome
Carlo
Franco
Carlo
Lorenzo
Marco
Bianchi
Neri
Rossi
Lanzi
Franco
35
Interrogazione 24
(insiemistiche)
Cognomi che sono anche nomi
select Nome
from Impiegato
intersect
select Cognome
from Impiegato
Nome
Franco
36
Interrogazione 25
(insiemistiche)
Nomi che non sono cognomi
select Nome
from Impiegato
except
select Cognome
from Impiegato
Nome
Mario
Carlo
Giuseppe
Lorenzo
Paola
Marco
37
Join esplicito
Abbiamo visto un modo di fare il join
mettendo le condizioni di join nella
clausola where
Si può utilizzare esplicitamente un
operatore di join
38
Interrogazione 26 (join
esplicito)
select
select
Impiegato.Nome,
Impiegato.Nome,Cognome,
Cognome,
Dipartimento.Città
Dipartimento.Città
from
from
Impiegato join Dipartimento
Impiegato,Dipartimento
On (Dipart =Dipartimento.Nome)
where
Dipart =
Dipartimento.Nome
39
Interrogazione 27 (join
esplicito riprende la 11)
Estrarre il nome e lo stipendio dei capi degli
impiegati che guadagnano piú dei loro capi
select I1.Nome, I1.Stipendio
from Impiegato I1, Impiegato I2, Supervisione
where I1.Matricola = Capo
and I2.Matricola = Impiegato
and I2.Stipendio > I1.Stipendio
select I1.Nome, I1.Stipendio
from (Impiegato I1 join Supervisione on
(I1.Matricola = Capo)) join Impiegato I2 on
(I2.Matricola = Impiegato)
where I2.Stipendio > I1.Stipendio
40
Outer join
Fino ad adesso abbiamo visto inner join
Parliamo adesso di outer join
Serve quando il join non è completo …

Completo: dato R1 join R2 on (…), per
ciascuna tupla di R1 esiste almeno una tupla di R2
che si combina con essa, e viceversa per R2
… se si vuole mantenere l’informazione anche
per quelle tuple che non partecipano al join
41
Tabelle “Guidatore” e “Automobile”
Nome
Cognome
NumPatente
Mario
Carlo
Marco
Rossi
Bianchi
Neri
VR 2030020Y
PZ 1012436B
AP 4544442R
Targa
Marca
Modello
NumPatente
AB 574 WW
AA 652 FF
BJ 747 XX
BB 421 JJ
Fiat
Fiat
Lancia
Fiat
Punto
Brava
Delta
Uno
VR 2030020Y
VR 2030020Y
PZ 1012436B
MI 2020030U
42
Inner join (“normale”)
select Nome,Cognome,Guidatore.NumPatente,
Targa
from Guidatore join Automobile on
(Guidatore.NumPatente=Automobile.NumPatente)
Nome Cognome NumPatente Targa
Mario
Mario
Carlo
Rossi
Rossi
Bianchi
VR 2030020Y
VR 2030020Y
PZ 1012436B
Marca Modello
AB 574 WW Fiat
Punto
AA 652 FF Fiat
Brava
BJ 747 XX
Lancia Delta
Join non completo
43
Outer left join (interrogazione 28)
select Nome,Cognome,Guidatore.NumPatente,
Targa
from Guidatore left join Automobile on
(Guidatore.NumPatente=Automobile.NumPatente)
Nome Cognome NumPatente
Targa
Marca Modello
Mario
Mario
Carlo
Rossi
Rossi
Bianchi
VR 2030020Y
VR 2030020Y
PZ 1012436B
AB 574 WW Fiat
Punto
AA 652 FF Fiat
Brava
BJ 747 XX
Lancia Delta
Marco
Neri
AP 4544442R
null
null
null
44
Outer right join
(interrogazione 29)
select Nome,Cognome,Guidatore.NumPatente,
Targa
from Guidatore right join Automobile on
(Guidatore.NumPatente=Automobile.NumPatente)
Nome Cognome NumPatente Targa
Marca Modello
Mario
Mario
Carlo
Rossi
Rossi
Bianchi
VR 2030020Y
VR 2030020Y
PZ 1012436B
AB 574 WW Fiat
Punto
AA 652 FF Fiat
Brava
BJ 747 XX
Lancia Delta
null
null
null
BB 421 JJ
Fiat
Uno
45
Outer full join (interrogazione 30)
select Nome,Cognome,Guidatore.NumPatente,
Targa
from Guidatore full join Automobile on
(Guidatore.NumPatente=Automobile.NumPatente)
Nome Cognome NumPatente
Targa
Marca Modello
Mario
Mario
Carlo
Rossi
Rossi
Bianchi
VR 2030020Y
VR 2030020Y
PZ 1012436B
AB 574 WW Fiat
Punto
AA 652 FF Fiat
Brava
BJ 747 XX
Lancia Delta
Marco
null
Neri
null
AP 4544442R
null
null
BB 421 JJ
null
Fiat
null
Uno
46
Join naturale (interrogazione 31)
select Nome,Cognome,Guidatore.NumPatente,
Targa
from Guidatore natural join Automobile
Nome Cognome NumPatente Targa
Mario
Mario
Carlo
Rossi
Rossi
Bianchi
VR 2030020Y
VR 2030020Y
PZ 1012436B
Marca Modello
AB 574 WW Fiat
Punto
AA 652 FF Fiat
Brava
BJ 747 XX
Lancia Delta
Attributo comune:
NumPatente
47
Interrogazioni nidificate
Clausola “where” su predicati logici in
cui le componenti sono confronti tra
valori
Possibile anche confrontare valori con il
risultato di una query (query annidata)
Di solito prima si esegue la query più
interna, ma ci sono eccezioni (per
esempio, passaggio di binding)
48
Interrogazioni nidificate
Parole chiave all e any:


any: specifica che la riga soddisfa la condizione se
risulta vero il confronto tra il valore dell’attributo
per la riga ed almeno uno degli elementi restituiti
dall’interrogazione
all: specifica che la riga soddisfa la condizione
solo se tutti gli elementi restituiti
dall’interrogazione nidificata rendono vero il
confronto
49
Interrogazione 32
Tutti i dati degli impiegati che lavorano in dipartimenti in
Firenze
select *
from Impiegato
where Dipart = any (select Nome
from Dipartimento
where Citta = ‘Firenze’)
= any corrisponde a in
50
Interrogazione 33 (simile alla 10)
Impiegati che hanno lo stesso nome di impiegati del dip
di Produzione
select I1.Nome
from Impiegato I1, Impiegato I2
where I1.Nome = I2.Nome
and I2.Dipart = ‘Produzione’
select Nome
from Impiegato
where Nome = any (select Nome
from Impiegato
where Dipart = ‘Produzione’)
51
Interrogazione 34
Dipartimenti in cui non lavorano persone con cognome
‘Rossi’
“diverso da”
select Nome
from Dipartimento
where Nome <> all (select Dipart
from Impiegato
where Cognome = ‘Rossi’)
select Nome
from Dipartimento
<> all corrisponde a not in
except
select Dipart
from Impiegato
where Cognome = ‘Rossi’
52
Interrogazione 35
Dipartimento dell’impiegato che guadagna lo stipendio
massimo
select Dipart
from Impiegato
where Stipendio = (select max(Stipendio)
from Impiegato)
Un solo
valore da
confrontare
select Dipart
from Impiegato
where Stipendio >= all (select Stipendio
from Impiegato)
Le due interrogazioni sono equivalenti
53
Scarica

parte teorica (formato ppt) - Dipartimento di Informatica