SQL, esempi
30/10/2014 Basi di dati SQL 1
30/10/2014 Basi di dati SQL 2
CREATE TABLE, esempi
CREATE TABLE corsi( codice numeric NOT NULL PRIMARY KEY, titolo character(20) NOT NULL, cfu numeric NOT NULL)
CREATE TABLE esami( corso numeric REFERENCES corsi (codice), studente numeric REFERENCES studenti (matricola), data date
NOT NULL, voto numeric NOT NULL, PRIMARY KEY (corso, studente))
La chiave primaria viene definita come NOT NULL anche se non lo specifichiamo (in Postgres)
30/10/2014 Basi di dati SQL 3
DDL, in pratica
• In molti sistemi si utilizzano strumenti diversi dal codice SQL per definire lo schema della base di dati
• Vediamo (per un esempio su cui lavoreremo)
30/10/2014 Basi di dati SQL 4
SQL, operazioni sui dati
• interrogazione: • SELECT
• modifica:• INSERT, DELETE, UPDATE
30/10/2014 Basi di dati SQL 5
Nome Età
Persone
RedditoAndrea 27
Maria 55Anna 50
Filippo 26Luigi 50
Franco 60Olga 30
Sergio 85Luisa 75
Aldo 2521
4235304020413587
15
MadreMaternità FiglioLuisa
AnnaAnnaMariaMaria
LuisaMaria
OlgaFilippoAndrea
Aldo
Luigi
PadrePaternità Figlio
LuigiLuigi
FrancoFranco
SergioOlga
FilippoAndrea
Aldo
Franco
30/10/2014 Basi di dati SQL 6
Istruzione SELECT (versione base)
SELECT ListaAttributiFROM ListaTabelle[ WHERE Condizione ]
• "target list"• clausola FROM • clausola WHERE
30/10/2014 Basi di dati SQL 7
Intuitivamente
SELECT ListaAttributiFROM ListaTabelle[ WHERE Condizione ]
• Prodotto cartesiano di ListaTabelle• Selezione su Condizione• Proiezione su ListaAttributi
30/10/2014 Basi di dati SQL 8
Selezione, proiezione e join
• Le persone che guadagnano più di 20, mostrando anche il padre e il reddito
PROJNome,Padre, Reddito (paternita JOIN Figlio =Nome
SELReddito>20 (persone))
select nome, padre, redditofrom persone, paternitawhere figlio = nome and reddito > 20
30/10/2014 Basi di dati SQL 9
Selezione e proiezione
• Nome e reddito delle persone con meno di trenta anni
PROJNome, Reddito(SELEta<30(Persone))
select nome, redditofrom personewhere eta < 30
30/10/2014 Basi di dati SQL 10
Selezione, senza proiezione
• Nome, età e reddito delle persone con meno di trenta anni
SELEta<30(Persone)
select *from personewhere eta < 30
30/10/2014 Basi di dati SQL 11
Proiezione, senza selezione
• Nome e reddito di tutte le personePROJNome, Reddito(Persone)
select nome, redditofrom persone
30/10/2014 Basi di dati SQL 12
Proiezione, con ridenominazione
• Nome e reddito di tutte le personeRENAnni Eta(PROJNome, Eta(Persone))
select nome, eta as annifrom persone
30/10/2014 Basi di dati SQL 13
Espressioni nella target list
select Reddito/12 as redditoMensilefrom Persone
30/10/2014 Basi di dati SQL 14
Condizione complessa
select *from personewhere reddito > 25
and (eta < 30 or eta > 60)
30/10/2014 Basi di dati SQL 15
Condizione “LIKE”
• Le persone che hanno un nome che inizia per 'A' e ha una 'd' come terza lettera
select * from persone where nome like 'A_d%'
30/10/2014 Basi di dati SQL 16
Cognome Filiale EtàMatricola
Neri Milano 455998Bruni Milano NULL9553
Impiegati
SEL (Età > 40) OR (Età IS NULL) (Impiegati)
Rossi Roma 327309 Rossi Roma 327309 Neri Milano 455998Bruni Milano NULL9553
Gestione dei valori nulli
• Gli impiegati la cui età è o potrebbe essere maggiore di 40
30/10/2014 Basi di dati SQL 17
selectcognome, filiale
from impiegati
select distinctcognome, filiale
from impiegati
Proiezione, attenzione
30/10/2014 Basi di dati SQL 18
Nome Età
Persone
RedditoAndrea 27
Maria 55Anna 50
Filippo 26Luigi 50
Franco 60Olga 30
Sergio 85Luisa 75
Aldo 2521
4235304020413587
15
MadreMaternità FiglioLuisa
AnnaAnnaMariaMaria
LuisaMaria
OlgaFilippoAndrea
Aldo
Luigi
PadrePaternità Figlio
LuigiLuigi
FrancoFranco
SergioOlga
FilippoAndrea
Aldo
Franco
30/10/2014 Basi di dati SQL 19
Selezione, proiezione e join
• I padri di persone che guadagnano più di 20
PROJPadre(paternita JOIN Figlio =Nome
SELReddito>20 (persone))
select distinct padrefrom persone, paternitawhere figlio = nome and reddito > 20
30/10/2014 Basi di dati SQL 20
• Le persone che guadagnano più dei rispettivi padri; mostrare nome, reddito e reddito del padre
PROJNome, Reddito, RP (SELReddito>RP
(RENNP,EP,RP Nome,Eta,Reddito(persone)JOINNP=Padre
(paternita JOIN Figlio =Nome persone)))
select f.nome, f.reddito, p.redditofrom persone p, paternita, persone fwhere p.nome = padre and
figlio = f.nome andf.reddito > p.reddito
30/10/2014 Basi di dati SQL 21
SELECT, con ridenominazione del risultato
select figlio, f.reddito as reddito, p.reddito as redditoPadre
from persone p, paternita, persone fwhere p.nome = padre and figlio = f.nome
and f.reddito > p.reddito
30/10/2014 Basi di dati SQL 22
Join esplicito
• Padre e madre di ogni persona
select paternita.figlio,padre, madrefrom maternita, paternitawhere paternita.figlio = maternita.figlio
select madre, paternita.figlio, padre from maternita join paternita on
paternita.figlio = maternita.figlio
30/10/2014 Basi di dati SQL 23
• Le persone che guadagnano più dei rispettivi padri; mostrare nome, reddito e reddito del padre
select f.nome, f.reddito, p.redditofrom persone p, paternita, persone fwhere p.nome = padre and
figlio = f.nome andf.reddito > p.reddito
select f.nome, f.reddito, p.redditofrom (persone p join paternita on p.nome = padre)
join persone f on figlio = f.nome
where f.reddito > p.reddito
30/10/2014 Basi di dati SQL 24
Join esterno: "outer join"
• Padre e, se nota, madre di ogni persona
select paternita.figlio, padre, madrefrom paternita left join maternita
on paternita.figlio = maternita.figlio
select paternita.figlio, padre, madrefrom paternita left outer join maternita
on paternita.figlio = maternita.figlio
• outer e' opzionale
30/10/2014 Basi di dati SQL 25
Ordinamento del risultato
• Nome e reddito delle persone con meno di trenta anni in ordine alfabetico
select nome, redditofrom personewhere eta < 30order by nome
30/10/2014 Basi di dati SQL 26
Unione
select A, Bfrom Runionselect A , Bfrom S
select A, Bfrom Runion allselect A , Bfrom S
30/10/2014 Basi di dati SQL 27
Notazione posizionale!
select padre, figlio from paternitaunionselect madre, figliofrom maternita
30/10/2014 Basi di dati SQL 28
Luisa
AnnaAnnaMariaMaria
LuisaMaria
OlgaFilippoAndrea
Aldo
Luigi
Figlio
LuigiLuigi
FrancoFranco
SergioOlga
FilippoAndrea
Aldo
Franco
Luisa
AnnaAnnaMariaMaria
LuisaMaria
OlgaFilippoAndrea
Aldo
Luigi
Padre Figlio
LuigiLuigi
FrancoFranco
SergioOlga
FilippoAndrea
Aldo
Franco
30/10/2014 Basi di dati SQL 29
Notazione posizionale, 2
select padre, figliofrom paternitaunionselect figlio, madrefrom maternita
NO!
select padre, figliofrom paternitaunionselect madre, figliofrom maternita
OK
30/10/2014 Basi di dati SQL 30
Notazione posizionale, 3
• Anche con le ridenominazioni non cambia niente:select padre as genitore, figliofrom paternitaunionselect figlio, madre as genitorefrom maternita
• Corretta:select padre as genitore, figliofrom paternitaunionselect madre as genitore, figlio from maternita
30/10/2014 Basi di dati SQL 31
Differenza
select Nomefrom Impiegatoexceptselect Cognome as Nomefrom Impiegato
30/10/2014 Basi di dati SQL 32
Intersezione
select Nomefrom Impiegatointersectselect Cognome as Nomefrom Impiegato
30/10/2014 Basi di dati SQL 33
Operatori aggregati: COUNT
• Il numero di figli di Franco
select count(*) as NumFigliDiFrancofrom Paternitawhere Padre = 'Franco'
30/10/2014 Basi di dati SQL 34
COUNT DISTINCT
select count(*) from persone
select count(reddito) from persone
select count(distinct reddito) from persone
30/10/2014 Basi di dati SQL 35
Altri operatori aggregati
• SUM, AVG, MAX, MIN
• Media dei redditi dei figli di Franco
select avg(reddito) from persone join paternita on nome=figlio where padre='Franco'
30/10/2014 Basi di dati SQL 36
Operatori aggregati e valori nulli
select avg(reddito) as redditomediofrom persone
30/10/2014 Basi di dati SQL 37
Operatori aggregati e target list
• un’interrogazione scorretta:
select nome, max(reddito)from persone
• di chi sarebbe il nome? La target list deve essere omogenea
select min(eta), avg(reddito)from persone
30/10/2014 Basi di dati SQL 38
• Il numero di figli di ciascun padre
select Padre, count(*) AS NumFiglifrom paternitagroup by Padre
Operatori aggregati e raggruppamenti
30/10/2014 Basi di dati SQL 39
Condizioni sui gruppi
• I padri i cui figli hanno un reddito medio maggiore di 25; mostrare padre e reddito medio dei figli
select padre, avg(f.reddito)from persone f join paternita on figlio = nome group by padre having avg(f.reddito) > 25
30/10/2014 Basi di dati SQL 40
Interrogazioni nidificate(nested query o subquery)
30/10/2014 Basi di dati SQL 41
Massimo e nidificazione
• La persona (o le persone) con il reddito massimo
select *from personewhere reddito = ( select max(reddito)
from persone)
30/10/2014 Basi di dati SQL 42
• nome e reddito del padre di Franco
select Nome, Redditofrom Persone, Paternitawhere Nome = Padre and Figlio = 'Franco'
select Nome, Redditofrom Personewhere Nome = ( select Padre
from Paternita where Figlio = 'Franco')
30/10/2014 Basi di dati SQL 43
• Nome e reddito dei padri di persone che guadagnano più di 20
select distinct P.Nome, P.Redditofrom Persone P, Paternita, Persone Fwhere P.Nome = Padre and Figlio = F.Nome
and F.Reddito > 20
select Nome, Redditofrom Personewhere Nome in (select Padre
from Paternitawhere Figlio = any (select Nome
from Personewhere Reddito > 20))
notare la distinct
30/10/2014 Basi di dati SQL 44
• Nome e reddito dei padri di persone che guadagnano più di 20
select distinct P.Nome, P.Redditofrom Persone P, Paternita, Persone Fwhere P.Nome = Padre and Figlio = F.Nome
and F.Reddito > 20
select Nome, Redditofrom Personewhere Nome in (select Padre
from Paternita, Persone where Figlio = Nomeand Reddito > 20)
30/10/2014 Basi di dati SQL 45
• Nome e reddito dei padri di persone che guadagnano più di 20, con indicazione del reddito del figlio
select distinct P.Nome, P.Reddito, F.Redditofrom Persone P, Paternita, Persone Fwhere P.Nome = Padre and Figlio = F.Nome
and F.Reddito > 20
select Nome, Reddito, ???? from Personewhere Nome in (select Padre
from Paternitawhere Figlio = any (select Nome
from Personewhere Reddito > 20))
30/10/2014 Basi di dati SQL 46
• Le persone che hanno almeno un figlio
select * from Persone where exists ( select *
from Paternita where Padre = Nome)
or exists ( select *
from Maternita where Madre = Nome)
30/10/2014 Basi di dati SQL 47
• I padri i cui figli guadagnano tutti più di 20
select distinct Padre from Paternita Z where not exists (
select * from Paternita W, Persone where W.Padre = Z.Padre
and W.Figlio = Nome and Reddito <= 20)
select distinct padrefrom paternita p1where padre NOT IN (select padre from paternita p2 join persone on figlio = nome where reddito < 40 )
30/10/2014 Basi di dati SQL 48
30/10/2014 Basi di dati SQL 49
• I padri i cui figli guadagnano tutti più di 20
select distinct Padre from Paternita where not exists (
select * from Persone where Figlio = Nome
and Reddito <= 20)
NO!!!
30/10/2014 Basi di dati SQL 50
Disgiunzione e unione (ma non sempre)select * from Persone where Reddito > 30
union select F.*from Persone F, Paternita, Persone Pwhere F.Nome = Figlio and Padre = P.Nome
and P.Reddito > 30
select *from Persone Fwhere Reddito > 30 or
exists (select *from Paternita, Persone Pwhere F.Nome = Figlio and Padre =
P.Nomeand P.Reddito > 30)
30/10/2014 Basi di dati SQL 51
Differenza e nidificazione
select Nome from Impiegatoexceptselect Cognome as Nome from Impiegato
select Nomefrom Impiegato Iwhere not exists (select *
from Impiegatowhere Cognome = I.Nome)
30/10/2014 Basi di dati SQL 52
Operazioni di aggiornamento
30/10/2014 Basi di dati SQL 53
INSERT INTO Persone VALUES ('Mario',25,52)
INSERT INTO Persone(Nome, Reddito, Eta) VALUES('Pino’,52,23)
INSERT INTO Persone(Nome, Reddito) VALUES('Lino',55)
INSERT INTO Persone ( Nome )SELECT PadreFROM PaternitaWHERE Padre NOT IN (SELECT Nome FROM Persone)
30/10/2014 Basi di dati SQL 54
Eliminazione di ennuple
DELETE FROM Tabella [ WHERE Condizione ]
30/10/2014 Basi di dati SQL 55
DELETE FROM PersoneWHERE Eta < 35
DELETE FROM PaternitaWHERE Figlio NOT in ( SELECT Nome FROM Persone)
DELETE FROM Paternita
30/10/2014 Basi di dati SQL 56
Modifica di ennuple
UPDATE NomeTabellaSET Attributo = < Espressione |
SELECT … | NULL | DEFAULT >
[ WHERE Condizione ]
30/10/2014 Basi di dati SQL 57
UPDATE Persone SET Reddito = 45WHERE Nome = 'Piero'
UPDATE Persone SET Reddito = Reddito * 1.1WHERE Eta < 30
Top Related