Il 0% ha trovato utile questo documento (0 voti)
7 visualizzazioni29 pagine

BDD - Linguaggio SQL

Caricato da

andreatardioli03
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
7 visualizzazioni29 pagine

BDD - Linguaggio SQL

Caricato da

andreatardioli03
Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 29

mercoledì 11 dicembre 2024

BASI DI DATI - LINGUAGGIO SQL


Introduzione
SQL (Structured Query Language) è un linguaggio con varie funzionalità:
contiene sia il DDL (permette di creare, modi care o eliminare gli oggetti
in un database ovvero agire sullo schema di database) sia il DML
(consente di leggere, inserire, modi care o eliminare i dati in un
database.).
Di questo linguaggio ne esistono varie versioni.

Speci che di linguaggio e terminologia:


- courier
usato per i termini del linguaggio (parole chiave e simboli)
Es.: where indica la parola chiave SQL “where”
- neretto
usato per termini variabili
Es.: NomeRelazione può rappresentare la stringa “Impiegati”
- […]
tutto ciò che è tra parentesi quadre è opzionale
Es.: [“abc”] può rappresentare tanto la stringa “abc” quanto la stringa
vuota
- {…}
tutto ciò che è tra parentesi gra e può essere ripetuto zero o più
volte
Es.: {“abc”} può rappresentare: “”, “abc”, “abcabc”, ecc.
- <…|…>
tutto ciò che è tra parentesi angolate separato da barre verticali è
alternativo
Es.: <“a” | “b” | “c”> può rappresentare “a”, oppure “b”, oppure “c”

De nizione dei dati in SQL


I domini sui quali ciascun attributo può assumere valori possono essere:
- domini elementari, prede niti nel linguaggio SQL
- domini de niti dall’utente a partire da quelli elementari con
opportune istruzioni SQL

La seguente semantica permette di rappresentare singoli caratteri o


stringhe

1
fi
fi
fi
fi
fi
ff
fi
character [ varying ] [ ( Lunghezza ) ] [ character set
NomeFamigliaCaratteri ]
• Lunghezza indica la lunghezza (numero di caratteri) della stringa; se
omesso si assume 1
• varying indica che la lunghezza è variabile; in tal caso Lunghezza
indica la lunghezza massima.
• character set NomeFamigliaCaratteri permette di specificare una
famiglia di caratteri di default
• Forme compatte: char per character e varchar per character
varying

Esempio: character(20) , character varying (1000), character set Greek,


varchar(50)

La seguente semantica permette di rappresentare singoli bit (booleani)


o stringhe di bit
bit [ varying ] [ ( Lunghezza ) ]
• Lunghezza indica la lunghezza (numero di caratteri) della stringa di
bit; se omesso si assume 1
• varying indica che la lunghezza è variabile; in tal caso Lunghezza
indica la lunghezza massima.

Es: bit(5), bit varying (100)

Le seguenti semantiche permettono di rappresentare valori numerici


esatti (interi o reali con parte decimale fissa)
numeric [ (Precisione [ , Scala ] )]
decimal [ (Precisione [ , Scala ] )]
integer
smallint
• numeric e decimal permettono di rappresentare numeri
decimali – sono sinonimi e si possono usare in modo
intercambiabile
• Precisione specifica il numero di cifre significative
• Scala specifica il numero di cifre dopo la virgola
La precisione massima possibile dipende dall’implementazione
Esempio: decimal(4):[-9999:+9999], numeric (6,3)[-999,999:+999,999]
integer e smallint permettono di rappresentare numeri interi

2
Il numero di bit utilizzati per la rappresentazione dipende
dall’implementazione
Il numero di bit utilizzati per integer deve essere maggiore o uguale al
numero di bit utilizzati per smallint

La seguente semantica permette di rappresentare valori reali in virgola


mobile
float [ (Precisione) ]
double precision
Real
I domini rappresentano numeri reali in virgola mobile, cioè tramite
mantissa m ed esponente e; il valore del numero è m⋅10e
float consente di definire la precisione (numero di cifre) della mantissa
La precisione di real e double precision è fissa ma per double
precision si usa il doppio dei bit di real

La seguente semantica permette di rappresentare istanti di tempo (date


e orari).
date
time[(Precisione)][ with time zone]
timestamp [(Precisione)][ with time zone]
Ciascuno dei domini precedenti è strutturato e decomponibile in un
insieme di campi
• date ha come campi day, month e year
• time ha come campi hour, minute and second
• timestamp ha come campi year, month, day, hour, minute and
second
Per time e timestamp è possibile specificare un valore di precisione
che indica il numero di cifre decimali da utilizzare per rappresentare le
frazioni di secondo
I valori di default sono:
- 0 per time (precisione al secondo)
- 6 per timestamp (precisione al microsecondo)
Se si specifica l’opzione with time zone è possibile accedere a due
campi opzionali timezone_hour e timezone_minute che
rappresentano la differenza rispetto all’ora di riferimento
La seguente semantica permette di rappresentare intervalli di tempo

3
interval UnitàDiTempo [ to UnitàDiTempo ]
Le due unità di tempo rappresentano le unità che devono essere
utilizzate per misurare l’intervallo
Per esempio interval year to month rappresenta un intervallo
espresso in anni e mesi
Le unità di misura possono essere year, month, day, hour, minute e
second
Poiché gli anni e i mesi non sono confrontabili con precisione le unità di
misura sono divise in due gruppi year e month da una parte e le altre
dall’altra
Per la prima unità di misura è possibile specificare una precisione che
indica il numero di cifre da utilizzare
Se la seconda unità di misura è second è possibile specificare una
precisione che indica il numero di cifre decimali che si devono usare per
le frazioni di secondo

Esempio: interval year(5) to month: permette di rappresentare


intervalli di lunghezza fino a 99999 anni e 11 mesi
interval day(4) to second(6): permette di rappresentare
intervalli di lunghezza fino a 9999 giorni e 23 ore, 59 minuti, e
59,999999 secondi

Definizione di domini in SQL


l’Istruzione CREATE DOMAIN definisce un dominio (semplice),
utilizzabile in definizioni di relazioni.
create domain NomeDominio as Tipo [Default][Vincoli ]

Esempio:
create domain Voto as smallint
default null
check(value>=18 and value<=30)

4
L’istruzione CREATE TABLE definisce uno schema di relazione e ne crea
un’istanza vuota
create table NomeTabella
(NomeAttributo Dominio [Default] [Vincoli]
{,NomeAttributo Dominio [ Default ] [ Vincoli ] } [ AltriVincoli ])

Esempio:
create table Impiegato(
Matricola character(6) primary key,
Nome character(20) not null,
Cognome character(20) not null,
Dipart character(15),
Stipendio numeric(9) default 0,
Citta character(15),
foreign key(Dipart) references Dipartimento(NomeDip)
on delete set null
on update cascade,
unique (Cognome,Nome)
)

La sintassi per specificare il valore di default (sia nell’istruzione CREATE


DOMAIN che nella CREATE TABLE) è la seguente
default < Valore | user | null >
Definizione di vincoli generici (sia intrarelazionali che interrelazionali)
tramite il costrutto check (lo vedremo però più avanti)
Vincoli intrarelazionali predefiniti: not null, primary key, unique
• not null: impone che un attributo non assuma valori nulli, va
indicato dopo l’attributo
• unique: si applica ad uno o più attributi e impone che essi
costituiscano una superchiave
• primary key: si applica ad uno o più attributi e impone che essi
costituiscano la chiave primaria; implica unique e not null; può
essere definito al più una volta su ciascuna tabella
Sintassi per unique e primary key : vengono specificati nella
porzione della definizione che abbiamo indicato con AltriVincoli
Se sono definiti su un solo attributo si può specificare il vincolo di
seguito alla definizione dell’attributo.

5
Esempio create table Impiegato(
Matricola character(6)primary key,
Nome character(20) not null,
Cognome character(20) not null,
unique (Cognome,Nome)
)
Vincoli interrelazionali predefiniti: references e foreign key
Per un attributo:
references NomeTabella (NomeAttributo)
Per più attributi:
foreign key (NomeAttributo{,NomeAttributo})
references NomeTabella(NomeAttributo {, NomeAttributo})

Esempio: create table Infrazioni(


Codice char(6) primary key,
Data date,
Vigile integer references Vigili (Matricola),
Prov char(2),
Numero char(6),
foreign key (Prov, Numero)
references Auto(Prov, Numero)
)

Per i vincoli di integrità referenziale è possibile definire delle politiche di


reazione alla violazione dei vincoli
Violazioni dei vincoli possono essere dovute a due cause:
modifiche nella tabella cui si fa riferimento
cancellazioni nella tabella cui si fa riferimento
Nel seguito chiameremo tabella interna quella su cui è definito il
vincolo e tabella esterna quella cui si fa riferimento
Reazioni a modifiche:
- cascade: il nuovo valore dell’attributo nella tabella esterna viene
riportato sulle corrispondenti righe della tabella interna
- set null: all’attributo referente viene assegnato il valore null
- set default: all’attributo referente viene assegnato il valore di
default
- no action: l’operazione viene proibita

6
Reazioni a cancellazioni:
- cascade: tutte le righe della tabella interna corrispondenti alla riga.
Cancellata nella tabella esterna vengono cancellate
- set null: all’attributo referente viene assegnato il valore null
- set default: all’attributo referente viene assegnato il valore di
default
- no action: l’operazione viene proibita

on < delete | update > < cascade | set null | set default | no
action >
Va specificato di seguito alla definizione del vincolo
comando ALTER TABLE
alter table NomeTabella
< alter column NomeAttributo
< set default NuovoDefault |
drop default > |
add constraint NuovoVincolo |
drop constraint NomeVincolo |
add column DefAttributo |
drop column NomeAttributo >

Operazioni su dati in SQL


Interrogazione viene attuata tramite istruzione SELECT, mentre la
modifica tramite le istruzioni INSERT, DELETE, UPDATE.

- Istruzione SELECT, possiamo immaginare che l’esecuzione avvenga


nel seguente modo: si calcola il prodotto cartesiano delle tabelle
elencate nella clausola FROM, si selezionano le righe che soddisfano
le condizione espresse nella clausola WHERE, vengono restituiti i
valori degli attributi che compaiono nella target list

MATERNITA’
PATERNITA’
Madre Figlio
Padre Figlio
Luisa Maria
Sergio Franco
Luisa Luigi
Luigi Olga
Anna Olga
Luigi Filippo
Anna Filippo
Franco Andrea
Maria Andrea
Franco Aldo
7 Maria Aldo
PERSONE
Nome Età Reddito
Andrea 27 21
Aldo 25 15
Maria 55 42
Anna 50 35
Filippo 26 30
Luigi 50 40
Franco 60 20
Olga 30 41
Sergio 85 35
Luisa 75 87

Nome e reddito delle persone con meno di


trenta anni Nome Reddito
Andrea 21
select nome,reddito Aldo 15
from persone
Filippo 30
where eta < 30

La sintassi più dettagliata della istruzione SELECT è la seguente:

select AttrEspr [[as] Alias ] {,AttrEspr [[as] Alias ] }


from Tabella [ [as] Alias] {,Tabella [[as] Alias]}
[ where Condizione ]

La Target List è la lista degli attributi della tabella risultato


Ogni attributo può essere indicato con il nome o con
NomeTabella.NomeAttributo
Gli elementi nella Target List sono, in generale, espressioni sui valori
degli attributi

8
È possibile usare l’abbreviazione * per indicare tutti gli attributi delle
tabelle elencate nella clausola FROM
Possono comparire ridenominazioni

select nome, età, reddito


from persone
where eta < 30

select *
from persone
where eta < 30

Esempio di ridenominazione:

select nome, reddito


from persone
where eta < 30

select nome
as giovane,
Nome Reddito Giovane Salario reddito as
Andrea 21 Andrea 21 salario
from persone
Aldo 15 Aldo 15
where eta <
Filippo 30 30 Filippo 30

Per formulare interrogazioni che coinvolgono più tabelle, queste


vengono elencate nella clausola FROM
Al prodotto cartesiano delle tabelle elencate nella clausola FROM,
vengono applicate le condizioni contenute nella clausola WHERE
Possono comparire ridenominazioni.

9
Nome Età Reddito Padre Figlio
Andrea 27 21 Sergio Franco
Andrea 27 21 Luigi Olga
Padre Figlio
Esempio: Andrea 27 21 Luigi Filippo
Sergio Franco
padri di Andrea 27 21 Franco Andrea
Luigi Olga persone che
Aldo 25 15 Sergio Franco
guadagnano
Luigi Filippo
più di venti Aldo 25 15 Luigi Olga
Franco Andrea milioni Aldo 25 15 Luigi Filippo

select Aldo 25 15 Franco Andrea


Tabella 1-3 padre Maria 55 42 Sergio Franco
Nome Età Reddito Maria 55 42 Luigi Olga
from
Andrea 27 21 persone, Maria 55 42 Luigi Filippo
Aldo 25 15
paternita Maria 55 42 Franco Andrea
where
Maria 55 42 Filippo 26 30 Sergio Franco
Filippo 26 30 Filippo 26 30 Luigi Olga
Luigi 50 40 Filippo 26 30 Luigi Filippo

Franco 60 20 Filippo 26 30 Franco Andrea

Olga 30 41 Luigi 50 40 Sergio Franco


Luigi 50 40 Luigi Olga
figlio=nome and reddito>20
Luigi 50 40 Luigi Filippo
Luigi 50 40 Franco Andrea
Franco 60 20 Sergio Franco
Franco 60 20 Luigi Olga
Franco 60 20 Luigi Filippo
Nome Età Reddito Padre Figlio Franco 60 20 Franco Andrea
Andrea 27 21 Franco Andrea Olga 30 41 Sergio Franco
Filippo 26 30 Luigi Filippo Olga 30 41 Luigi Olga

Olga 30 41 Luigi Olga Olga 30 41 Luigi Filippo


Olga 30 41 Franco Andrea

10
select padre
from persone, paternita
where figlio=nome and reddito>20

Nome Età Reddito


Andrea 27 21
Aldo 25 15
Maria 55 42
Anna 50 35
Nome Età Reddito Filippo 26 30
Andrea 27 21 Luigi 50 40
Aldo 25 15 Franco 60 20
Olga 30 41
Sergio 85 35
L’operatore WHERE ammette come
argomento una espressione booleana Luisa 75 87
È possibile combinare predicati semplici
mediante gli operatori and, or, not
Gli operatori =,<>,<,>,<=,>= possono essere utilizzati per confrontare
un’espressione sui valori degli attributi con una costante o un’altra
espressione. Esistono altri operatori.
L’operatore LIKE consente il confronto tra stringhe in cui compaiono
caratteri speciali: _ : un carattere qualsiasi, % : una stringa di lunghezza
arbitraria.

11
Esempio: persone che hanno un nome che inizia per ‘A’ e ha una ‘d’
come terza lettera

select *
from persone
where nome like ‘A_d%'

Per selezionare attributi il cui valore è (o non è) nullo si possono usare i


predicati: is null, is not null.

Esempio: impiegati la cui età è o potrebbe essere maggiore di 40

select *
from impiegati
where eta > 40 or eta is null
• SQL E ALGEBRA RELAZIONALE
Consideriamo il seguente schema di base di dati e la seguente
interrogazione su esso: R1(A1,A2) R2(A3,A4)

select R1.A1, R2.A4


from R1, R2
where R1.A2 = R2.A3

Come esprimiamo la stessa interrogazione in Algebra Relazionale?


Clausola FROM→ prodotto cartesiano→ R1 IXI R2
Clausola WHERE → selezione→ σ A2=A3 (R1 IXI R2)
Target list → proiezione→ π A1,A4 (σ A2=A3 (R1 IXI R2))

La scrittura equivale dunque in AR a : π A1,A4 (σ A2=A3 (R1 IXI R2))


Dall’esempio precedente si vede come sia possibile stabilire una
relazione tra gli elementi di una SELECT e gli operatori dell’algebra
relazionale

12
• SQL E CALCOLO RELAZIONALE
Consideriamo il seguente schema di base di dati e la seguente
interrogazione su esso: R1(A1,A2) R2(A3,A4)

select R1.A1, R2.A4


from R1, R2
where R1.A2 = R2.A3

Come esprimiamo la stessa interrogazione nel Calcolo Relazionale su


tuple con dich. di range?
Target list → target list
Clausola FROM→ range list
Clausola WHERE → formula

La scrittura equivale a CR su tuple con dich. di range a { t1.A1,t2.A4 |


t1(R1),t2(R2) | t1.A2=t2.A3 }

Per quanto riguarda SQL e Join negli esempi visti finora il join veniva
realizzato mediante una opportuna condizione di join espressa nella
clausola WHERE

Esempio: padri di persone che guadagnano più di venti milioni


π (paternita IXI σ (persone)
Padre Figlio =Nome Reddito>20

Nome Età Reddito


Padre Figlio Andrea 27 21
Sergio Franco Aldo 25 15
Luigi Olga Maria 55 42
Luigi Filippo Filippo 26 30
Franco Andrea Luigi 50 40
Franco 60 20
Olga 30 41

13
Nome Età Reddito Padre Figlio
Andrea 27 21 Sergio Franco
Andrea 27 21 Luigi Olga
Andrea 27 21 Luigi Filippo
select distinct padre Andrea 27 21 Franco Andrea
from persone, paternita Aldo 25 15 Sergio Franco
where figlio=nome
Aldo 25 15 Luigi Olga
and reddito>20
Aldo 25 15 Luigi Filippo
Aldo 25 15 Franco Andrea
Maria 55 42 Sergio Franco
Nome Età Reddito Padre Figlio Maria 55 42 Luigi Olga

Andrea 27 21 Franco Andrea Maria 55 42 Luigi Filippo

Filippo 26 30 Luigi Filippo Maria 55 42 Franco Andrea

Olga 30 41 Luigi Olga Filippo 26 30 Sergio Franco


Filippo 26 30 Luigi Olga
Filippo 26 30 Luigi Filippo
Filippo 26 30 Franco Andrea
Luigi 50 40 Sergio Franco
Luigi 50 40 Luigi Olga
Luigi 50 40 Luigi Filippo
Luigi 50 40 Franco Andrea
Franco 60 20 Sergio Franco
Franco 60 20 Luigi Olga
Franco 60 20 Luigi Filippo
Franco 60 20 Franco Andrea
Olga 30 41 Sergio Franco
Olga 30 41 Luigi Olga
Olga 30 41 Luigi Filippo
Olga 30 41 Franco Andrea

14
SQL offre la possibilità di indicare esplicitamente un’operazione di Join
Sintassi:
select AttrEspr [[as] Alias] {, AttrEspr [[as] Alias] }
from Tabella [[as] Alias]
{ [TipoJoin] join Tabella [[as]Alias] on CondizioneDiJoin }
[ where AltraCondizione ]

Esempio: padre e madre di ogni persona


select paternita.figlio,padre, madre
from maternita, paternita
where paternita.figlio =
maternita.figlio

select madre, paternita.figlio, padre


from maternita join paternita on
paternita.figlio = maternita.figlio

Madre Figlio
Padre Figlio
Luisa Maria
Sergio Franco
Luisa Luigi
Luigi Olga
Anna Olga
Luigi Filippo
Anna Filippo
Franco Andrea
Maria Andrea
Franco Aldo
Maria Aldo

Madre Padre Paternità.Figlio


Anna Luigi Olga
Anna Luigi Filippo
Maria Franco Andrea
Maria Franco Aldo

15
TipoJoin può essere uno tra: inner, natural, right outer, left outer, full
outer
- Join naturale: padre e madre di ogni persona
paternita IXI maternita

select madre, paternita.figlio, padre


from maternita join paternita on
paternita.figlio = maternita.figlio

select madre, paternita.figlio, padre


from maternita natural join paternita
- Join esterno: padre, e se nota, madre di ogni persona
select paternita.figlio, padre, madre
from paternita left outer join
maternita on paternita.figlio =
maternita.figlio

select paternita.figlio, padre, madre


from paternita left join maternita
on paternita.figlio =
maternita.figlio

È possibile ordinare il risultato di una query sulla base di uno o più


attributi tramite la clausola ORDER BY:
order by AttrDiOrdinamento [asc|desc]
{,AttrDiOrdinamento [asc|desc]}

Nome e reddito delle persone con meno di


trenta anni in ordine alfabetico
Nome Età Reddito
select nome, reddito Aldo 25 15
from persone
where eta < 30 asc Andrea 27 21
Filippo 26 30

select nome, reddito Nome Età Reddito


from persone
Filippo 26 30
where eta < 30
order by nome desc Andrea 27 21
Aldo 25 15
16
Nelle espressioni della target list possiamo avere anche espressioni che
calcolano valori a partire da insiemi di tuple:
conteggio, minimo, massimo, media, somma
sintassi base:
count(<*|[distinct|all] ListaAttributi>)
<sum|max|min|avg>([distinct|all] AttrEspr)

Padre Figlio select count(*) as NumFigliDiFranco


from Paternita
Sergio Franco
where Padre = ‘Franco'
Luigi Olga
Luigi Filippo NumFigliDiFranco

Franco Andrea 2

Franco Aldo

Padre Figlio
select * from Paternita
Franco Andrea
where Padre = ‘Franco'
Franco Aldo

Esempio di count e valori nulli

select count(*)from Persone


Nome Età Reddito 4
Andrea 27 21
select count(reddito)from
Aldo 25 NULL Persone 3
Maria 55 21
select count(distinct
Anna 50 35
reddito)from Persone 2

Altri operatori aggregati sono : sum, avg, max e min


avg : Media
select avg(reddito) as redditomedio
from persone Redditomedio
N.B. Il NULL non viene contato nella media 26

17
max : Massimo
Un’interrogazione scorretta:
select nome, max(reddito)
from persone
Intuitivamente tale interrogazione vorrebbe trovare la persona che
guadagna di più, ma:
Se ne esiste più di una?
Se invece di max ci fosse avg, o sum?
Non è possibile inserire nella target list operatori aggregati ed
espressioni a livello di singola tupla (come ad esempio nomi di attributi)
Fanno eccezione le query che usano raggruppamenti (vedi appresso)
Una interrogazione corretta:
select min(eta), max(reddito)
from persone
Gli operatori aggregati vengono applicati ad un insieme di tuple
Negli esempi visti finora, a tutte le tuple del risultato
Può essere utile applicarli a sottoinsiemi delle tuple del risultato
Clausola group by :
group by ListaAttributi

Esempio: numero figli di ciascun padre

Padre Figlio select padre, count(*) AS NumFigli


from paternita
Sergio Franco
group by Padre
Luigi Olga Padre NumFigli

Luigi Filippo Sergio 1

Franco Andre Luigi 2


a Franco 2
Franco Aldo

Viene prima eseguita l’interrogazione senza group by e senza operatori


aggregati
Si raggruppano le tuple che assumono gli stessi valori sugli attributi
elencati nella group by
Si applicano gli operatori aggregati a ciascun gruppo
Nella target list di una query che fa uso della clausola group by
possono comparire soltanto:

18
- Attributi che compaiono nella clausola group by
- Operatori aggregati
Infatti in ogni tupla t del risultato dobbiamo avere un valore unico per
tutte le tuple t’ del gruppo che dà luogo a t

Esempio:
Un’interrogazione scorretta:
select padre, f.nome, avg(f.reddito),
from persone f join paternita on figlio = nome
group by padre
Per ogni padre abbiamo una unica tupla nel risultato…
…ma per ogni padre abbiamo più valori di f.nome
La restrizione che abbiamo appena visto in alcuni casi può risultare
eccessiva:
select padre, avg(f.reddito), p.reddito
from persone f join paternita on figlio = nome join
persone p on padre = p.nome
group by padre
In questo caso, pur non comparendo nella group by, l’attributo
p.reddito assume un valore unico per ogni tupla del risultato
Sarebbe possibile, in casi analoghi al precedente, consentire nella
target list la presenza di attributi che non compaiono nella group by
Per semplicità si preferisce però mantenere anche in questi casi la
restrizione che abbiamo visto
Come possiamo eseguire l’interrogazione precedente?
Basta mettere l’attributo p.reddito nella group by
select padre, avg(f.reddito), p.reddito
from persone f join paternita on
figlio = nome join persone p on padre = p.nome
group by padre, p.reddito

La clausola group by raggruppa le righe in sottoinsiemi


Può essere necessario considerare soltanto i sottoinsiemi che
soddisfano una condizione
Se la condizione è valutabile a livello delle singole righe possiamo usare
la clausola where
Altrimenti si usa la clausola having:
having CondizioniAggregate

19
Esempio: padri i cui figli hanno un reddito medio maggiore di 25
select padre, avg(f.reddito)
from persone f join paternita on figlio = nome
group by padre
having avg(f.reddito) > 25

Esempio: padri i cui figli sotto i 30 anni hanno un reddito medio


maggiore di 20
select padre,avg(f.reddito)
from persone f join paternita on figlio = nome
where f.eta < 30
group by padre
having avg(f.reddito) > 20

Si può usare la having senza la group by; in tal caso tutte le tuple del
risultato sono considerate un unico gruppo
Sintatticamente è possibile esprimere nella having condizioni sugli
attributi che non compaiono nella group by…
…è però preferibile esprimere tali condizioni nella clausola where e
lasciare nella having solo le condizioni sugli operatori aggregati

Riassunto della sintassi della SELECT:


select ListaAttributiOEspressioni
from ListaTabelle
[ where CondizioniSemplici ]
[ group by ListaAttributiDiRaggruppamento ]
[ having CondizioniAggregate ]
[ order by ListaAttributiDiOrdinamento ]

-Unione, Intersezione e differenza: In SQL è possibile utilizzare anche gli


operatori insiemistici di unione, intersezione e differenza
Intersezione e differenza sono esprimibili anche tramite altri costrutti del
linguaggio,l’unione no (cfr. calcolo su tuple)
Sintassi:
selectSQL {<union |intersect |except> [all] selectSQL}
Gli operatori insiemistici assumono come default l’eliminazione di
duplicati nel risultato
Volendo mantenere i duplicati basta far seguire l’operatore dalla parola
chiave all

20
Non è richiesto che gli schemi siano identici…
…ma solo che gli attributi siano in ugual numero e abbiano domini
compatibili
La corrispondenza non avviene in base al nome ma in base alla
posizione

Esempio: Elencare tutti i genitori (sia padri che madri)


select padre
from paternita
union
select madre
from maternita
Quali nomi per gli attributi del risultato? Si usano quelli del primo
operando

Madre Figlio Padre Figlio Padre


Luisa Maria Sergio Franco Sergio
Luisa Luigi Luigi
Luigi Olga
Anna Olga Franco
Luigi Filippo
Anna Filippo Luisa
Franco Andrea
Maria Andrea Anna
Maria Aldo Franco Aldo Maria

Esempio: elencare tutte le coppie genitore figlio


La seguente interrogazione non darebbe il risultato voluto:
select padre, figlio
from paternita
union
select figlio, madre
from maternita
La corrispondenza avviene in base alla posizione
Anche ridenominando si ha lo stesso problema
select padre as genitore, figlio
from paternita
union

21
select figlio, madre as genitore
from maternita

Esempio: Selezionare i nomi di impiegati che sono anche cognomi


select Nome from Impiegato
intersect
select Cognome from Impiegato
Si può esprimere come:
select I.Nome
from Impiegato I, Impiegato J
where I.Nome = J.Cognome

Esempio: Selezionare i nomi di impiegati che NON sono cognomi


select Nome from Impiegato
except
select Cognome from Impiegato
Si può esprimere con select nidificate (vedi appresso)

-Interrogazioni nidificate: le condizioni atomiche nella clausola where


permettono anche:
• di effettuare il confronto fra un attributo e il risultato di una
sottointerrogazione
• di utilizzare quantificazioni esistenziali

Esempio: nome e reddito del padre di Franco


select Nome, Reddito
from Persone, Paternita
where Nome=Padre and Figlio='Franco‘

select Nome, Reddito


from Persone
where Nome =(select Padre from Paternita where
Figlio= ‘Franco')

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

22
Il confronto tra un attributo e una interrogazione nidificata pone un
problema: si confronta il valore assunto da un attributo su una certa
tupla con l’insieme di valori (in generale più di uno) che
costituiscono il risultato della interrogazione nidificata
Si usano le parole chiave:
• any se si richiede che il confronto debba essere verificato per almeno
una tupla dell’insieme
• all se si richiede che il confronto debba esser verificato per ciascuna
tupla dell’insieme
L’appartenenza può essere verificata anche con gli operatori in e not
in
Si hanno le seguenti equivalenze:
• in ⇔ =any
• not in ⇔ <>all

Esempio: Nome e reddito dei padri di persone che guadagnano più di


20 milioni
Seleziona il padre della persone che guadagnano più di venti milioni
Seleziona nome e reddito dei padri individuati
Seleziona Nome e Reddito dei padri individuati

select Nome, Reddito


from persone
where Nome in(select Padre from Paternita
where Figlio = any(select Nome from Persone
where Reddito > 20))

Negli esempi visti la query nidificata veniva eseguita in maniera


indipendente dalla query che la racchiude.
In alcuni casi è però necessario che la query nidificata faccia riferimento
al contesto della query che la racchiude
Nella query nidificata si può far riferimento a variabili definite nella query
esterna.
L’interrogazione interna viene eseguita una volta per ciascuna tupla
dell’interrogazione esterna
Cioè una volta per ogni valore assunto dalla variabile passata
dall’esterno all’interno

23
Esempio: CANTANTE (Nome,Canzone) AUTORE(Nome,Canzone)
Trovare i cantautori (cioè le persone che hanno cantato almeno una
canzone scritta da loro)
select Nome from Cantante C
where Nome in(select Nome from Autore
where Autore.Canzone= C.Canzone)

Regole di visibilità:
• In un blocco si può fare riferimento a variabili definite in esso o in
blocchi più esterni;
• non è possibile fare riferimento a variabili definite in blocchi più interni
• non è possibile fare riferimenti a variabili definite in blocchi allo stesso
livello
• se un nome di variabile è omesso, si assume riferimento alla variabile
più “vicina”

Un altro operatore che può essere utilizzato con le interrogazioni


nidificate è l’operatore exists
Ammette come parametro una interrogazione nidificata e restituisce il
valore vero se e solo se l’interrogazione restituisce un risultato non
vuoto

Esempio: le persone che hanno almeno un figlio


select * from Persone P
where exists(select * from Paternita
where Padre=P.Nome)
or exists(select * from Maternita
where Madre = P.Nome)

Esempio: padri i cui figli guadagnano tutti più di venti milioni


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)

24
Operazioni di aggiornamento
Le operazioni di aggiornamento possono essere operazioni di:
- inserimento: insert
- eliminazione: delete
- modifica: update
di una o più ennuple di una relazione sulla base di una condizione che
può coinvolgere anche altre relazioni.

Inserimento-sintassi:
insert into Tabella [ ( Attributi ) ]
values( Valori )

insert into Tabella [ ( Attributi )]


IstruzioneSelect

Esempi.
insert into persone values ('mario',25,52)

insert into persone(nome, eta, reddito)


values('pino',25,52)

insert into persone(nome, reddito)


values('lino',55)

insert into persone ( nome )


select padre
from paternita
where padre not in (select nome
from persone)
L’ordinamento degli attributi e dei valori (se presente) è significativo
Le due liste debbono avere lo stesso numero di elementi
Se la lista di attributi è omessa, si fa riferimento a tutti gli attributi della
relazione, secondo l’ordine con cui sono stati definiti
Se la lista di attributi non contiene tutti gli attributi della relazione, per gli
altri viene inserito un valore nullo (che deve essere permesso) o un
valore di default

25
Eliminazione-sintassi
delete from Tabella
[ where Condizione ]
Esempi.
delete from persone
where eta < 35

delete from paternita


where figlio not in (select nome
from persone)

delete from paternita

Elimina le ennuple che soddisfano la condizione


Può causare (se i vincoli di integrità referenziale sono definiti con
politiche di reazione cascade) eliminiazioni da altre relazioni
Ricordare: se la where viene omessa, si intende where true

Modifica-sintassi
update NomeTabella
set Attributo = < Espressione |
IstruzioneSelect | null | default >
{, Attributo = < Espressione |
IstruzioneSelect | null | default >}
[ where Condizione ]

Esempi.
update persone set reddito = 45
where nome = 'piero'

update persone
set reddito = reddito * 1.1
where eta < 30

26
Vincoli di integrità generici
Il costrutto check consente di specificare vincoli di integrità sia
intrarelazionali che interrelazioanli
Sintassi: check( Condizione )

Esempi.
create table Impiegato(
Matricola smallint primary key,
Cognome character(20) not null,
Nome character(20) not null,
Sesso character not null check (Sesso in
(‘M’,‘F’))
Stipendio integer,
Superiore character(6),
check (Stipendio <= (select Stipendio
from Impiegato J
where Superiore =
J.Matricola))
)

Le asserzioni sono vincoli che non sono associati a nessuna tabella o


attributo in particolare ma appartengono allo schema della base di
dati
Sintassi: create assertion NomeAss
check(Condizione )

Esempio.
create assertion AlmenoUnImpiegato
check (1 <= (select count(*)
from Impiegato ))

Viste
In SQL è possibile definire viste (ovvero relazioni i virtuali)
Sintassi:
create view NomeVista [ ( ListaAttributi )] as IstruzioneSelect
[ with [ local | cascaded ] check option ]

Esempio.
Impiegati del reparto amministrazione che guadagnano più di 10

27
create view ImpiegatiAmmin
(Matricola,Nome,Cognome,Stipendio) as
select Matricola,Nome,Cognome,Stipendio
from Impiegato
where Dipart = 'Amministrazione‘ and Stipendio > 10

E’ possibile effettuare interrogazioni sulle viste come se fossero tabelle


reali
select Matricola, Cognome, Nome
from ImpiegatiAmmin
where Cognome=‘Rossi’

È possibile definire una vista in termini di altre viste


Non sono possibili però definizioni ricorsive:
Né immediate (definizione di una vista in termini di sé stessa)
Né transitive (V1 definita in termini di V2, V2 in termini di V3,…,Vn in
termini di V1)

create view ImpiegatiAmminPoveri


as
select *
from ImpiegatiAmmin
where Stipendio < 50

La clausola check option si usa nel contesto delle viste aggiornabili


Se la clausola compare indica che sono ammessi soltanto
aggiornamenti che non violano le condizioni di definizione della vista
local: controllo delle condizioni di definizione della vista in questione
cascaded: controllo delle condizioni di definizione di tutte le viste a
partire dalle quali è definita quella in questione

create view ImpiegatiAmminPoveri


as
select *
from ImpiegatiAmmin
where Stipendio < 50
with local check option
Se a seguito di una modifica Stipendio vale 60, la modifica non viene
accettata
Se a seguito di una modifica Stipendio vale 8 la mod. viene accettata

28
Ogni elemento di un DB può essere protetto (tabelle, attributi, viste,
domini, etc.)
Il creatore di una risorsa assegna i privilegi agli altri
Un utente predefinito _system rappresenta il database administrator e
ha accesso completo a tutte le risorse
Un privilegio é caratterizzato da:
- La risorsa
- L’ utente che garantisce i privilegi
- L’ utente che riceve i privilegi
- L’azione permessa sulla risorsa
- Se il privilegio può essere passato ad altri utenti o no
SQL offre sei tipi di privilegi
- insert: per inserire nuovi oggetti nella risorsa
- update: per modificare il contenuto della risorsa
- delete: per rimuovere un oggetto dalla risorsa
- select: per accedere al contenuto della risorsa mediante una query
- references: per creare un vincolo di integrità referenziale con la
risorsa
- usage: per usare la risorsa nella definizione di uno schema

Concessione di privilegi
grant < Privileges | all privileges > on Resource
to Users [ with grant option ]

with grant option specifica se il privilegio di propagare i privilegi


ad altri utenti deve essere garantito
Esempio:
grant select on Department to Stefano

Rimozione di privilegi
revoke Privileges on Resource from Users
[ restrict | cascade ]

restrict o cascade indica se il privilegio deve essere rimosso solo


per l’utente in questione o anche per gli utenti cui lui lo ha concesso
Esempio:
revoke select on Department from Stefano

29

Potrebbero piacerti anche