1. Data Query Language

Permette di fare interrogazioni (query).

Ogni query ha la seguente struttura di base:

SELECT Attributo {{AS alias}, Attributo {AS alias}}
FROM Tabella
[WHERE Condizione]

La clausola SELECT indica gli attributi da includere nel risultato.

La clausola FROM indica i nomi di relazioni dalle quali si estraggono i dati.

La clausola WHERE indica una condizione booleana che i dati devono soddisfare.

Il DBMS esegue il prodotto cartesiano delle relazioni indicate nella FROM, valuta la WHERE riga per riga e seleziona gli attributi indicati dalla SELECT.

WHERE

La WHERE è un’espressione booleana di predicati semplici:

OP può essere uno dei seguenti: <, < =, >, > =, =, < > (vuol dire \neq).

BETWEEN

SELECT Matricola
FROM Studente
WHERE Età BETWEEN 19 AND 22

Stringhe

In SQL le stringhe vanno sempre racchiuse tra due ‘ o tra due “.

Ex.
WHERE nome = "Aldo" OR nome = 'Giulio'

Valori Duplicati

Quando si fa una query, SQL non rimuove automaticamente i valori duplicati: tocca specificarlo con la clausola DISTINCT.

Questa clausola può essere inserita anche all’interno dell’operatore aggregato COUNT(...).

SELECT DISTINCT Nome
FROM Insegnante
WHERE Città = 'Bologna'

ORDER BY

Questa clausola, che compare alla fine dell’interrogazione, ordina le righe del risultato.

La sintassi è: ORDER BY Attributo [ASC|DESC|] {, Attributo [ASC|DESC]}

Le condizioni vengono valutate in ordine: a pari valore del primo, si considera il secondo, e così via.

Ex.
SELECT *
FROM Insegnante
WHERE Città = "Milano"
ORDER BY Nome ASC, Cognome DESC

Funzioni Aggregate

Il risultato di una query con funzioni aggregate dipende dalla valutazione del contenuto di un insieme di tuple.

I principali operatori aggregati sono: COUNT(….), SUM(….), MAX(…), MIN(…), AVG(…).

SELECT SUM(Stipendio)
FROM Insegnante
WHERE Stipendio >= 2000

Attenzione: attributi e funzioni aggregate non possono essere nella stesa target list di una select.

// La seguente query è SBAGLIATA
SELECT Nome, SUM(Stipendio)
FROM Insegnante
WHERE Stipendio >= 2000

Attenzione: si ricorda che la WHERE viene valutata riga per riga.

// La seguente query è SBAGLIATA
SELECT Matricola
FROM Studente
WHERE MAX(Voto)

LIKE

Questo operatore permette, all’interno di una WHERE, di effettuare confronti parziali, usando due caratteri speciali:

WHERE Nome LIKE "A_%"

Date

Le date vengono specificate con formato YYYY-MM-DD.

È possibile fare confronti tra di esse con gli operatori <, < =, >, > =, =, <>, BETWEEN ... AND, LIKE.

Inoltre si possono anche usare gli operatori DAY(...), MONTH(...), YEAR(...).

Raggruppamento

È possibile applicare operatori aggregati a sottoinsiemi di tuple, utilizzando:

SELECT Matricola, AVG(Voto) AS VotoMedio, COUNT(*)
FROM Esame
GROUP BY Matricola
HAVING VotoMedio > 25

In presenza di un raggruppamento, nella target list di una SELECT si possono inserire solo:

Join

La sintassi è:

SELECT Attr
FROM Tab [[AS Alias]] {[TipoJoin] JOIN Tab [[AS] Alias] ON JoinCondition}
[WHERE ...]

TipoJoin può valere:

NULL

Per fare una verifica sugli attributi che accettano valori nulli, si utilizza nella clausola WHERE il costrutto:

Attributo IS NULL
// Oppure
Attributo IS NOT NULL

Attenzione! SQL utilizza una logica a tre valori: TRUE (T), FALSE (F), UNKNOWN (U).

[Inserire qui immagine slide 48]

Operazioni Insiemistiche tra Query

Si possono concatenare più query tra loro usando gli operatori insiemistici: Query OP Query.

OP può essere UNION, INTERSECT, EXCEPT, ALL e di default vale ALL.

I duplicati vengono eliminati, a meno che non venga specificata l’opzione ALL.

I risultati delle query devono essere tra loro compatibili, ovvero:

Query Nidificate

Nelle clausole WHERE e HAVING possono comparire predicati che confrontano un attributo (o un’espressione di attributi) con il risultato di una intera query SQL:

AttrEspr OP < ANY | ALL> QuerySQL

OP è un operatore qualsiasi tra >, > =, <, < =, = , <>.

ANY: il predicato è vero se almeno una riga restituita dalla query QuerySQL soddisfa il confronto

ALL: il predicato è vero se tutte le righe restituite dalla query QuerySQL soddisfano il confronto

Al pari delle set-query, la target list delle sub-query devono essere compatibili con l’attributo (o gli attributi, vedremo tra poco) della query a loro più esterna, ovvero:

I nomi dei campi delle tabelle (e gli alias che andiamo a definire) nelle query SQL a più livelli sono utilizzabili nel livello in cui vengono definiti e in tutti i livelli inferiori.

IN e NOT IN

L’operatore IN è equivalente a = ANY. L’operatore NOT IN è equivalente a <> ALL.

EXISTS

È possibile utilizzare il quantificatore esistenziale sul risultato di una query SQL:

WHERE EXISTS (QuerySQL)
// Oppure
WHERE NOT EXISTS (QuerySQL)

Costruttore di Tupla

Il confronto con la query nidificata può coinvolgere più di un attributo.Gli attributi devono essere racchiusi da un paio di parentesi tonde, chiamate costruttore di tupla.

SELECT *
FROM Insegnante I1
WHERE (Nome, Cognome) IN (
	SELECT I2.Nome, I2.Cognome
	FROM Insegnante I2
	WHERE I1.Matricola <> I2.Matricola)