Sei sulla pagina 1di 20

1 Introduzione

Il linguaggio SQL (Structured Query Language) è nato con lo scopo di poter eseguire con facilità:
• la definizione e la creazione di un database relazionale;
• le diverse operazioni di gestione dei dati, quali l’inserimento, la cancellazione e la variazione dei
record di un archivio;
• l’interrogazione del database a scopo informativo.

Il linguaggio è basato su costrutti semplici e facili da imparare. Le sue caratteristiche, infine, sono
standardizzate in modo che un utente, cambiando DBMS, non debba apprendere un nuovo
linguaggio per usare la base di dati.

Le interrogazioni che si costruiscono con SQL sono un’estensione di quelle che si realizzano con
sequenze di operazioni relazionali, in quanto con SQL è possibile, come nelle query di Access,
effettuare calcoli, raggruppamenti e ordinamenti.
Come abbiamo visto nel precedente capitolo, Access permette di costruire una query in modalità
QBE e di visualizzarne il corrispondente codice SQL. È anche possibile costruire l’interrogazione
in SQL e, passando alla Visualizzazione Struttura, esaminare la versione QBE della query. Per
imparare il linguaggio è molto utile passare da una modalità all’altra e osservare come una frase
di SQL viene rappresentata in QBE oppure come una query QBE, di cui si conoscono gli effetti,
viene tradotta in SQL.

La conoscenza di SQL è di grande importanza anche nello sviluppo di applicazioni direttamente


con Access in modalità QBE per le seguenti ragioni:
• ci sono interrogazioni che non si riescono a sviluppare con le QBE di Access;
• come si vedrà più avanti nel capitolo, per scrivere interrogazioni annidate in modalità QBE
bisogna inserire un comando SQL nella riga dei criteri;
• per inserire in una maschera una casella combinata che permetta la scelta da un elenco di dati
estratti da una tabella, bisogna scrivere un’interrogazione SQL da inserire tra le proprietà della
casella;
• scritta un’interrogazione in modalità QBE e dovendola modificare, è spesso più facile e rapido
modificare il codice SQL dell’interrogazione che la versione QBE originale.

Nel seguito del capitolo faremo riferimento al seguente database di esempio.

Un’azienda è articolata in un certo numero di dipartimenti. I dipendenti sono assegnati ai


diversi dipartimenti che hanno a capo un manager responsabile della gestione.

Le entità individuate sono:


• Impiegato con le informazioni sui dipendenti: un codice identificativo (chiave primaria), nome,
cognome, residenza e stipendio. Stipendio e codice identificativo sono attributi di tipo nume-
rico, gli altri sono di tipo carattere.
• Dipartimento con le informazioni sui dipartimenti: un codice che individua il dipartimento (la
chiave primaria), il nome del dipartimento e il suo indirizzo. Tutti gli attributi sono di tipo
carattere.

Tra Impiegato e Dipartimento si individuano le due associazioni Comprendere e Coordinare come


è mostrato nel diagramma E/R in figura.

208 5. IL LINGUAGGIO SQL © Istituto Italiano Edizioni Atlas


Modello E/R

Comprendere è un’associazione uno Partecipazione facoltativa per Lettura del modello


a molti tra Dipartimento e Impiega- Dipartimento, nell’ipotesi che Ogni impiegato deve essere com-
to: un impiegato è compreso in un ci siano dipartimenti senza preso in un solo dipartimento; ogni
solo dipartimento, un dipartimento è dipendenti assegnati. dipartimento può comprendere uno
composto da molti impiegati. o più impiegati.

N Comprendere 1
Impiegato Dipartimento
Coordinare mette in re- 1 Coordinare N
lazione un dipartimento ID {PK} Codice {PK}
con il dipendente che lo Nome Descrizione
dirige. È un’associazione Cognome Sede
uno a molti perché un Residenza Partecipazione
dipendente può essere a Stipendio facoltativa di Impiegato
capo di più di un diparti- in quanto solo alcuni Lettura del modello
mento, mentre un dipar- dipendenti sono Ogni impiegato può coordinare uno
timento ha un solo ma- manager. o più dipartimenti; ogni dipartimen-
nager. to deve essere coordinato da un solo
impiegato.

Il passaggio dal modello concettuale al modello relazionale porta al seguente schema di database
dove, come al solito, gli attributi sottolineati rappresentano le chiavi primarie, mentre le chiavi
esterne sono indicate in corsivo.

Dipartimento contiene il codice del dipartimento di


Manager rappresenta l’as-
appartenenza di un dipendente e modella l’asso-
sociazione Coordinare e
ciazione uno a molti Comprendere e Impiegato.
contiene il valore della chia-
ve primaria del dipendente
Impiegati (ID, Nome, Cognome, Residenza, Stipendio, Dipartimento) che dirige il dipartimento.
Dipartimenti (Codice, Descrizione, Sede, Manager)

Nella seguente figura sono mostrate le tabelle Impiegati e Dipartimenti con alcuni dati di esempio.

L’impiegato con ID = 6 lavora


nel dipartimento Magazzino,
diretto da Margherita Colombi.
L’impiegato con ID = 5 non è
assegnato ad alcun dipartimento.
Si tratta di un dipendente
appena assunto e non ancora
assegnato ad alcun dipartimento.

Margherita Colombi (ID=10)


è a capo sia del Magazzino
che della Produzione.

© Istituto Italiano Edizioni Atlas 5. IL LINGUAGGIO SQL 209


2 Caratteristiche generali del linguaggio SQL
Il linguaggio SQL è un linguaggio non procedurale che è diventato uno standard tra i linguaggi
per la gestione di database relazionali.
La natura non-procedurale (o dichiarativa) del linguaggio SQL è stata già sottolineata nel
Capitolo 1: con SQL l’interrogazione al database si esegue precisando solamente dove stanno i
dati e cosa si vuole ottenere, cioè definendo solo quali sono l’input e l’output desiderato.
Dopo una prima versione introdotta da IBM alla fine degli anni ’70 per un prototipo di ricerca
denominato System R, negli anni ’80 fu adottato con il nome attuale come linguaggio per i
software DBMS prodotti dalla IBM (DB2 e SQL/DS).
Nel 1986 l’ANSI (American National Standards Institute) pubblicò il primo standard del linguag-
gio SQL, al quale seguì lo standard dell’ISO (International Standards Organization) pubblicato nel
1987. Successivamente le specifiche del linguaggio vennero precisate e ampliate: gli aggiorna-
menti degli standard portarono alla versione, detta SQL2, pubblicata nel 1992 da ISO (ISO 9075)
e alla successiva, indicata come SQL3, pubblicata nel 1999 da ISO come ISO 9075-2.
Oggi il linguaggio SQL viene usato in tutti i prodotti DBMS come linguaggio di comandi per
l’utente della base di dati (ricordiamo Oracle, MySQL, SQLServer, Access).
Le diverse versioni del linguaggio SQL sono in genere aderenti agli standard internazionali, ma
ci sono sicuramente delle differenze che possono essere individuate attraverso la documentazio-
ne fornita con gli specifici software.
Le parole-chiave che costituiscono i comandi del linguaggio SQL possono essere usate in modo
interattivo, scrivendole direttamente sulla tastiera nel momento in cui si vogliono attivare. Tutta-
via in molti ambienti i comandi possono essere inviati al sistema attraverso un’interfaccia grafica,
che utilizza menu, finestre e icone per guidare l’utente nella costruzione dell’istruzione SQL.
La terminologia del linguaggio SQL è analoga a quella di Access dove un database è costituito
da tabelle, che rappresentano le relazioni; gli attributi sono le colonne della tabella e i record
sono le righe della tabella.

Il linguaggio SQL consente all’utente di:

• Definire il database, la struttura delle tabelle che lo compongono, gli indici, le associazioni tra
le tabelle e le viste logiche. Un elenco di comandi SQL che assolvono a funzioni di Data
Definition Language (DDL) è presentato nel Paragrafo 4.

• Modificare i dati contenuti nel database, con le operazioni di inserimento, variazione e cancel-
lazione, ed effettuare le interrogazioni. I comandi Insert, Update, Delete e Select, che apparten-
gono al Data Manipulation Language (DML) di SQL, sono discussi nei Paragrafi 5 e 6.

• Definire gli utenti e controllare gli accessi al database. I comandi Grant e Revoke, che apparten-
gono alle funzioni di Data Control Language (DCL) di SQL, sono presentati nel Paragrafo 13.

• Gestire e controllare le transazioni con un sottoinsieme del linguaggio che prende il nome di
Transaction Control Language (TCL). I comandi Commit e Rollback, che sono stati introdotti
nel Capitolo 1, saranno approfonditi nel Capitolo 6, con esempi relativi al software MySQL.

Il linguaggio SQL fornisce inoltre gli opportuni comandi per definire in modo facile i tabulati di
uscita dei risultati (report), per recuperare i dati quando accade un’interruzione del programma,
un guasto nei supporti magnetici o un malfunzionamento del sistema, per definire le viste degli
utenti sul database, per garantire la sicurezza dei dati nei confronti degli accessi di più utenti.

210 5. IL LINGUAGGIO SQL © Istituto Italiano Edizioni Atlas


3 Identificatori e tipi di dati
Il linguaggio SQL utilizza i caratteri alfabetici, le cifre decimali, gli operatori aritmetici e di
confronto (+ - / * = < >), più altri caratteri che assumono particolari significati nella sintassi delle
istruzioni e che verranno descritti nel seguito.
Gli identificatori (nomi di tabelle e di attributi) sono costituiti da sequenze di caratteri di
lunghezza massima uguale a 18 caratteri: devono iniziare con una lettera e possono anche
contenere il carattere _.
Il nome di un attributo, ovvero di una colonna di una tabella, è identificato per mezzo della
notazione abituale:
NomeTabella.NomeAttributo
nella quale il nome della tabella e il nome dell’attributo vengono separati da un punto. Il nome
della tabella può essere omesso se non ci sono ambiguità nell’identificazione dell’attributo.
Nella dichiarazione della struttura di una tabella occorre specificare il tipo dei dati scelto per gli
attributi.
I tipi standard del linguaggio SQL sono:

BOOLEAN Valore logico True, False


CHARACTER(n) Stringa di lunghezza n n da 1 a 15000
DATE Data nella forma MM/GG/AA
TIME Ora nella forma HH:MM
INTEGER(p) Numero intero con precisione p p da 1 a 45
SMALLINT Numero intero con precisione 5 da -32768 a 32767
INTEGER Numero intero con precisione 10 da -2.147.483.648 a 2.147.483.647
DECIMAL(p,s) Numero decimale con precisione p da 1 a 45 e s da 0 a p
p e s cifre decimali
REAL Numero reale con mantissa valore 0 oppure valore
di precisione 7 assoluto da 1E-38 a 1E+38
FLOAT (o DOUBLE Numero reale con mantissa valore 0 oppure valore
PRECISION) di precisione 15 assoluto da 1E-308 a 1E+308
FLOAT(p) Numero reale con mantissa p da 1 a 45
di precisione p

Per i dati numerici la precisione p indica il numero massimo di cifre che il numero può contenere,
esclusi il segno e il punto decimale.
Per i numeri decimali il valore s indica il numero di cifre che seguono il punto decimale.
I dati numerici floating point sono memorizzati in forma esponenziale; la precisione riguarda solo
le cifre della mantissa e indica il numero di cifre significative del dato.
La parola NUMERIC può essere usata al posto di DECIMAL.
La parola CHARACTER è equivalente a CHARACTER(1), e può essere abbreviata con CHAR.
DECIMAL è equivalente a DECIMAL(15,0).
Altre abbreviazioni sono:
• CHAR(n) invece di CHARACTER(n);
• INT(p) invece di INTEGER(p);
• DEC(p,s) invece di DECIMAL(p,s).

© Istituto Italiano Edizioni Atlas 5. IL LINGUAGGIO SQL 211


Occorre osservare che alcune versioni di SQL in specifici ambienti DBMS differiscono dallo
standard nell’indicazione dei tipi di dati. Le stesse considerazioni valgono anche per le successive
istruzioni del linguaggio: in diverse versioni del linguaggio SQL ci possono essere varianti nella
sintassi e nei termini utilizzati. Per risolvere questi problemi è opportuno sempre controllare gli
esempi presentati nei manuali per l’utente o nell’help in linea del linguaggio.
Le costanti stringa sono delimitate dai caratteri ' o ". Il delimitatore standard è l’apice '.
Nelle colonne della tabella gli attributi che hanno un valore non disponibile, o non definito,
assumono il valore Null. Il valore Null non è mai uguale a nessun altro valore: è diverso dal valore
zero per i dati numerici e dalla stringa vuota (") per i dati alfanumerici.
Negli ordinamenti il valore Null compare, di norma, all’inizio delle sequenze crescenti e alla fine
delle sequenze decrescenti.
Le costanti numeriche possono avere o non avere il segno + oppure –. Nei numeri decimali la
parte intera è separata dalle cifre decimali attraverso il punto. I numeri in floating point possono
essere rappresentati in forma esponenziale, per esempio –1.2E+7.
Nelle operazioni di confronto i numeri sono controllati in accordo con il loro valore algebrico,
mentre le stringhe sono confrontate carattere per carattere a partire da sinistra secondo il loro
valore lessicale, cioè secondo il codice ASCII e ignorando la differenza tra caratteri maiuscoli e
minuscoli (non case-sensitive). Nelle scrittura delle condizioni possono essere usati gli operatori
NOT, AND e OR.
Tutti i risultati di confronti numerici o stringa che riguardano attributi con valore Null sono
considerati sconosciuti, perché Null non è uguale, maggiore o minore di nessun altro valore.
Il linguaggio SQL può solo controllare la presenza o l’assenza di Null in una colonna.

4 Comandi DDL di SQL: la definizione delle tabelle


Le tabelle vengono definite con il comando CREATE TABLE, seguito dal nome della tabella
seguito, tra parentesi, dall’elenco degli attributi. Per ogni attributo occorre specificare il nome e
il tipo di dato. Gli attributi possono essere qualificati mediante diverse clausole che permettono
di definire: la chiave primaria, le chiavi esterne, l’obbligatorietà e il valore di default di un campo.

ESEMPIO 1
Creazione delle tabelle Impiegati e Dipartimenti.
ID è chiave primaria Campi obbligatori: non
della tabella. sono ammessi valori nulli
in Nome e Cognome.
CREATE TABLE Impiegati(
ID smallint primary key, Il valore da attribuire a
Nome char(20) not null, Residenza in caso di
Cognome char(30) not null, valore nullo.
Residenza char(20) default '*** Manca Residenza',
Stipendio decimal(9,2),
Dipartimento char(5) references Dipartimenti(Codice),
UNIQUE(Cognome, Nome, Dipartimento)
);

Ogni comando Vieta la presenza di valori duplicati in Dipartimento è chiave


SQL termina con una colonna o in un insieme di esterna associata a Codice.
il punto e virgola. colonne: non ci possono essere due Crea un vincolo di integrità
dipendenti con identico nome e referenziale con Dipartimenti.
cognome nello stesso dipartimento.

212 5. IL LINGUAGGIO SQL © Istituto Italiano Edizioni Atlas


Le clausole PRIMARY KEY e REFERENCES possono essere inserite, come la clausola UNIQUE,
in righe isolate: questa caratteristica permette di dichiarare chiavi primarie o chiavi esterne
formate da più campi. Nella definizione di una chiave esterna si può anche precisare cosa
deve fare il DBMS nel caso di cancellazione di una riga nella tabella collegata o di variazione
del valore della chiave primaria associata alla chiave esterna. Un esempio è mostrato nel
seguente comando per creare la tabella Dipartimenti.

CREATE TABLE Dipartimenti( Codice è chiave primaria della tabella.


Codice char(5),
Descrizione char(20) not null, Nella colonna Descrizione non ci possono
Sede char(20), essere valori duplicati. Descrizione identifica
Manager smallint, univocamente una riga della tabella.
Primary Key (Codice),
Unique (Descrizione),
Manager è chiave esterna associata
Foreign Key (Manager) references Impiegati(ID) al campo ID della tabella Impiegati.
On Delete set null
On Update cascade
); La cancellazione di una riga di Impiegati
L’aggiornamento di un ID associato a Manager implica che i valori di Manager associati
si riflette a catena sui valori di Manager. all’ID di quella riga assumano valore nullo.

Secondo la precedente dichiarazione, se nella tabella Impiegati si cancella il record con


ID=10, cioè il record di Margherita Colombi, il campo Manager dei record di Dipartimenti con
valore 10 (cioè i dipartimenti Magazzino e Produzione) assume il valore nullo. Se a Margherita
Colombi viene assegnato un nuovo valore di ID esso viene attribuito anche al campo Manager
nelle righe dei dipartimenti Magazzino e Produzione.

Foreign Key (Manager) references Impiegati(ID)


Impedisce di cancellare un record di
On Delete no action
Impiegati correlato alla chiave esterna
On Update no action
di Dipartimenti o di modificare il valore
Dichiarazione di default: le due della chiave primaria di un record di
dichiarazioni si equivalgono. Impiegati (ID) se tale valore compare
nel campo Manager di Dipartimenti.
Foreign Key (Manager) references Impiegati(ID)

Equivale alle opzioni Access: Elimina


Foreign Key (Manager) references Impiegati(ID) record correlati a catena, Aggiorna
On Delete cascade campi collegati a catena che si
On Update cascade possono operare nella definizione
delle associazioni tra tabelle.

La struttura di una tabella può essere modificata in un secondo tempo con il comando ALTER
TABLE, per aggiungere una nuova colonna (ADD) a quelle già esistenti, oppure per togliere
una colonna (DROP).

Esempio
Inserisce in Impiegati una nuova colonna di nome
ALTER TABLE Impiegati
Nascita per registrare la data di nascita del dipendente.
ADD Nascita date;

ALTER TABLE Impiegati Elimina da Impiegati la colonna di nome Residenza: il


DROP Residenza; comando elimina anche i dati contenuti nella colonna.

© Istituto Italiano Edizioni Atlas 5. IL LINGUAGGIO SQL 213


L’istruzione CREATE INDEX viene utilizzata per creare un nuovo indice su una tabella esisten-
te, indicando il nome della tabella e il nome dell’attributo o degli attributi ai quali associare
l’indice. Se non si vuole che ci siano valori duplicati per l’attributo associato all’indice, occorre
usare la clausola UNIQUE. Una tabella o un indice possono essere eliminati con il comando
DROP, seguito dal nome della tabella o dell’indice.

Esempio
Crea l’indice IndiceImpiegati sui campi Cognome e
CREATE UNIQUE INDEX IndiceImpiegati Nome di Impiegati: non ci possono essere dipendenti
ON Impiegati(Cognome, Nome); con lo stesso cognome e lo steso nome.

DROP INDEX IndiceImpiegati ON Impiegati; Cancella l’indice IndiceImpiegati da Impiegati.

DROP TABLE Impiegati; Elimina struttura e dati della tabella Impiegati.

I comandi illustrati rappresentano la parte del linguaggio SQL che fa riferimento alla catego-
ria dei comandi definiti con la sigla DDL (Data Definition Language), cioè il linguaggio che
consente di implementare il modello logico dei dati sulle memorie di massa del computer.
Occorre osservare che nelle versioni moderne dei prodotti DBMS le operazioni di creazione di
tabelle e di indici, oltre che di modifica alla struttura della tabella o di cancellazione di tabelle
e indici, vengono effettuate, come in Access, attraverso un’interfaccia interattiva che facilita il
lavoro dell’utente, il quale può anche non conoscere la sintassi dei comandi sopra illustrati.

5 I comandi per la manipolazione dei dati


I valori degli attributi nelle righe della tabella possono essere inseriti, aggiornati o cancellati
rispettivamente con i comandi INSERT, UPDATE e DELETE.
È importante notare che nei comandi Update e Delete compare la clausola Where per effetto della
quale è possibile operare su molte righe, anziché su una sola riga per volta: basta indicare dopo
Where una condizione che deve essere verificata dalle righe che si vogliono modificare o cancellare.

ESEMPIO 2
Eseguire operazioni di manipolazione sulla tabella Impiegati.

INSERT INTO Impiegati


(ID, Nome, Cognome, Residenza, Stipendio, Dipartimento) Inserimento di una riga
nella tabella Impiegati.
VALUES(20, 'Mario', 'Rossini', 'Caserta', 31500, 'Mag');

UPDATE Impiegati
SET Dipartimento = 'Prod' Assegnamento del dipendente con
WHERE ID = 20; ID=20 al dipartimento Produzione.

DELETE FROM Impiegati Cancellazione del dipendente con


WHERE ID = 20; ID=20 dalla tabella Impiegati.

UPDATE Impiegati
SET Stipendio = Stipendio * 1.05 Aumenta del 5% lo stipendio ai dipendenti
WHERE Dipartimento = 'Prod'; del dipartimento Produzione.

214 5. IL LINGUAGGIO SQL © Istituto Italiano Edizioni Atlas


DELETE FROM Impiegati Cancella i dipendenti del dipartimento
WHERE Dipartimento = 'R&S'; Ricerca & Sviluppo.

Manca la clausola WHERE: il comando svuota la


DELETE FROM Impiegati;
tabella Impiegati dai dati, ma rimane la sua struttura.

Come già detto a proposito della creazione delle tabelle, nell’uso pratico del linguaggio, le
operazioni di inserimento, così come quelle di modifica e di cancellazione, vengono facilitate
mediante l’uso di maschere video che guidano l’utente nelle operazioni di trattamento dei dati,
all’interno di un ambiente software basato sull’uso di interfacce grafiche amichevoli.
Si pensi, nel caso di Access, all’uso delle maschere e alla possibilità di manipolare dati agendo
direttamente sulla Visualizzazione Foglio dati di una tabella.
Quindi i comandi di tipo DML (Data Manipulation Language) del linguaggio SQL rimangono
nascosti all’utente che può effettuare le operazioni di manipolazione senza conoscere la sintassi
delle istruzioni.

ESERCIZI da 1 a 2 pag. 249 e da da 40 a 41 pag. 251

6 Interrogazioni con SQL: il comando Select


Un’importante caratteristica del linguaggio SQL è la sua capacità di estrarre le informazioni
desiderate dal database mediante interrogazioni. Queste funzionalità sono fornite dal comando
SELECT che è semplice da usare e allo stesso tempo molto potente.
Il comando Select riflette la natura dichiarativa del linguaggio SQL, e le interrogazioni sulle tabelle
del database sono eseguite specificando solo cosa si vuole ottenere, senza doversi preoccupare
di problemi quali: le modalità di rappresentazione dei dati e i percorsi per ritrovarli nelle memorie
di massa.

La struttura base del comando Select è descritta nel seguente schema:

Un elenco di espressioni, che coinvolgono le


SELECT Elenco di espressioni colonne, da mostrare. * per indicare tutte le colonne.

FROM Tabelle La tabella, o le tabelle, usate nell’interrogazione.

WHERE Condizioni ; Una espressione logica che specifica quali righe considerare. Espressione
booleana ottenuta componendo confronti con gli operatori AND OR e NOT.

Esempio: interrogazioni su una sola tabella.

Cognome, nome e residenza dei dipendenti


del dipartimento di codice Prod.

SELECT Cognome, Nome, Residenza


FROM Impiegati
WHERE Dipartimento = 'Prod';

SELECT ID, Cognome, Nome ID, Cognome, Nome dei


FROM Impiegati dipendenti che lavorano alla
WHERE Dipartimento = 'Prod' AND Residenza = 'Torino'; produzione e risiedono a Torino.

© Istituto Italiano Edizioni Atlas 5. IL LINGUAGGIO SQL 215


Tutti i dati dei dipendenti che abitano a Roma.

SELECT *
FROM Impiegati
WHERE Residenza = 'Roma';

Il comando Select possiede i due predicati ALL e DISTINCT. Con il predicato ALL si richiede che
nel risultato dell’interrogazione siano incluse tutte le righe, anche se duplicate, che soddisfano
alle condizioni contenute nel comando. Questo predicato è di default ed in genere è omesso.

SELECT * SELECT ALL *


I due comandi
FROM Impiegati si equivalgono. FROM Impiegati
WHERE Residenza = 'Milano'; WHERE Residenza = 'Milano';

Se viene specificato il predicato DISTINCT le righe duplicate nella tabella risultante sono ridotte
a una. Per esempio, se si desidera ottenere l’elenco di tutte le località di residenza dei dipendenti,
senza duplicati, si deve usare la clausola DISTINCT prima dell’indicazione dell’attributo.

SELECT DISTINCT Residenza SELECT Residenza


FROM Impiegati; FROM Impiegati;

La presenza del predicato


DISTINCT in un comando
Select impone che una riga
sia inclusa nella tabella risul-
tante solo se non c’è un’al-
tra riga con gli stessi valori.

Come si è anticipato nel Capitolo 3, i DBMS commerciali, per ragioni di efficienza, non rispettano
strettamente il modello relazionale, che non ammette la presenza di righe duplicate in una
tabella. Il predicato DISTINCT fa in modo che un comando Select produca una tabella coerente
con tale modello.

La tabella che si ottiene come risultato dell’interrogazione ha di norma un’intestazione delle


colonne che riporta i nomi degli attributi; se si vuole modificare tale intestazione, occorre
rinominare la colonna usando la clausola AS.

SELECT ID AS Matricola, Nome, Cognome Elenco degli impiegati con ID, Nome
FROM Impiegati; e Cognome, ma usando Matricola
come intestazione della colonna ID.

Con il comando SELECT si può richiedere il calcolo di espressioni basate sugli attributi della
tabella; la tabella risultante contiene delle colonne con i risultati del calcolo per ogni riga. Tali
colonne possono avere un’intestazione opportuna utilizzando la parola AS. In assenza di AS
l’intestazione della colonna con l’espressione viene costruita dal sistema in modo differente a
seconda dell’implementazione. Nel caso di Access il nome è Espr1 per la prima espressione, Espr2
per la seconda espressione e così via.

216 5. IL LINGUAGGIO SQL © Istituto Italiano Edizioni Atlas


Gli impiegati del magazzino con l’importo
dello stipendio e quello del nuovo
stipendio se fosse aumentato del 5%.

SELECT Cognome, Nome, Stipendio AS Attuale, Stipendio*1.05 AS Nuovo


FROM Impiegati
WHERE Dipartimento = 'Mag';

Gli importi di Stipendio in


Impiegati non sono modificati.

SELECT Cognome, Nome, Residenza, Stipendio


Elenca i dipendenti con retribuzione
FROM Impiegati
di almeno 55000 euro
WHERE Stipendio >= 55000;

SELECT Cognome, Nome, Residenza, Stipendio


Interrogazione parametrica: lo
FROM Impiegati
stipendio minimo è scelto dall’utente
WHERE Stipendio >= [Retribuzione minima?]; al momento dell’interrogazione.

Si osservi che per controllare la presenza di valori nulli si deve usare il predicato IS NULL, mentre
è errato ricercare tali valori in altro modo, come è mostrato di seguito. Si ricorda, a proposito, che
il dipendente con ID=5 non è assegnato ad alcun dipartimento.

SELECT ID AS Matricola, Cognome, Nome Per elencare i dipendenti senza dipartimento


FROM Impiegati di assegnazione, si devono riconoscere le
WHERE Dipartimento IS NULL; righe con valori nulli nel campo Dipartimento.

SELECT ID AS Matricola, Cognome, Nome


FROM Impiegati Ricerca una stringa vuota in Dipartimento.
WHERE Dipartimento = '';

L’interrogazione produce un elenco vuoto


perché in Impiegati non ci sono righe con una
stringa di caratteri vuota in Dipartimento.

Per scrivere un’interrogazione in SQL nell’ambiente di Access, bisogna creare una nuova query
accedendo alla Visualizzazione Struttura, e chiudere la finestra di dialogo Mostra tabella senza
scegliere alcuna tabella. Poi si deve fare clic sulla scelta che è diventata la proposta del pulsante
Visualizza.

© Istituto Italiano Edizioni Atlas 5. IL LINGUAGGIO SQL 217


Appare una finestra come quella in figura che permette di scrivere l’interrogazione desiderata.

Le istruzioni del linguaggio SQL sono a formato libero e terminano con il carattere punto e
virgola: un comando SQL può essere scritto liberamente su una o più righe e le parole chiave del
linguaggio possono essere scritte indifferentemente a caratteri maiuscoli o minuscoli.
In un comando SQL possono comparire commenti, con la convenzione che si considera un
commento tutto quello che compare in una riga di seguito alla sequenza di caratteri “-- “.
Per esempio, i due comandi SELECT mostrati di seguito sono entrambi corretti e sono
sintatticamente identici; sono stati anche inseriti: un commento che occupa parte di una riga e
tre commenti che occupano un’intera riga.

SELECT Matricola, Cognome, Nome -- Esempio di commento


FROM Studenti
WHERE Provincia = 'BO';
--
-- Il seguente comando SELECT è identico al precedente
--
Select Matricola, Cognome, Nome From Studenti Where Provincia = 'BO';

7 Le operazioni relazionali nel linguaggio SQL


Le operazioni fondamentali dell’algebra relazionale sono realizzate in SQL con il comando Select,
secondo le diverse forme consentite dalla sintassi del comando. Se si vuole rispettare una delle
regole del modello relazionale, che non consente la presenza di righe uguali all’interno della
stessa tabella, basta porre accanto alla parola Select la clausola Distinct: con questa specificazione
la tabella ottenuta non conterrà righe duplicate.

• La selezione, che estrae da una relazione solo le righe che soddisfano a una certa condizione,
viene realizzata nel linguaggio SQL specificando la condizione di selezione nella clausola Where
del comando Select.

Esempio

σP Impiegati Selezione di Impiegati per Stipendio < 31000

L’elenco con tutti i dati dei dipendenti con


SELECT *
stipendio minore di 31000 euro, si ottiene con
FROM Impiegati
una selezione sulla tabella Impiegati estraendo
WHERE Stipendio < 31000;
le righe per le quali: Stipendio < 31000.

• L’operazione di proiezione, che permette di ottenere una relazione contenente solo alcuni
attributi della relazione di partenza, si realizza scrivendo l’elenco degli attributi richiesti dopo
la parole Select.

218 5. IL LINGUAGGIO SQL © Istituto Italiano Edizioni Atlas


Esempio

ΠL Impiegati Proiezione di Impiegati su Cognome, Nome, ID


L’elenco di tutti i dipendenti con cognome,
SELECT Cognome, Nome, ID
nome e matricola, si ottiene con una proiezione
FROM Impiegati;
di Impiegati sulle colonne richieste.

• La congiunzione di tabelle. Il comando Select può operare su più tabelle, specificandone i


nomi, (separati da virgola) nella clausola From e scrivendo la condizione di congiunzione (cioè
la condizione che fa corrispondere le righe di una tabella con quelle dell’altra) nella clausola
Where. Nella quasi totalità dei casi si vogliono costruire degli equi-join, per cui la condizione
da scrivere nella clausola Where consiste nell’uguaglianza tra attributi di due tabelle.

Esempio

ImpiegatiFK DipartimentiPK Congiunzione di Impiegati su Dipartimento


e Dipartimenti su Codice

SELECT * L’elenco di tutti i dipendenti con i dati del dipartimento dove


FROM Impiegati, Dipartimenti lavorano, si ottiene con la congiunzione delle tabelle Impiegati e
WHERE Dipartimento = Codice; Dipartimenti secondo gli attributi comuni Dipartimento e Codice.

SELECT *
Per maggiore chiarezza, o se ci
FROM Impiegati, Dipartimenti sono attributi con il medesimo nome
WHERE Impiegati.Dipartimento = Dipartimenti.Codice; nelle due tabelle, si usa la dot
notation, specificando oltre al nome
dell’attributo anche quello della
Condizione di uguaglianza tra attributi:
tabella alla quale appartengono.
esempio di equi-join. Sono combinate solo
le righe che soddisfano alla condizione.

Nella versione di SQL adottata da Access il join viene indicato, in accordo con la terminologia
introdotta nel Capitolo 3, come inner join. Se la precedente interrogazione viene realizzata con
Access in modalità QBE e, successivamente, si accede alla query in visualizzazione SQL, si legge
(una volta ripulito dalle parentesi inutili) il seguente comando:

SELECT Impiegati.*, Dipartimenti.*


FROM Dipartimenti INNER JOIN Impiegati ON Dipartimenti.Codice =
Impiegati.Dipartimento;

INNER-JOIN definisce la congiunzione.


La condizione di congiunzione è scritta
nella stessa clausola FROM dopo ON.

La sintassi adottata da Access è una delle sintassi ammesse fra gli standard di SQL2, mentre il
modo di costruire le congiunzioni presentato all’inizio del paragrafo è quello dello standard di
base del linguaggio.
Va precisato che Access (come tutti gli SQL che ammettono tale ultima sintassi) accetta ed esegue
correttamente le interrogazioni costruite secondo lo standard di base. Naturalmente, quando il
comando Select è costruito direttamente da Access partendo da una QBE, l’interrogazione è
realizzata secondo gli standard tipici dell’implementazione.

© Istituto Italiano Edizioni Atlas 5. IL LINGUAGGIO SQL 219


Impiegati JOIN Dipartimenti

Nella congiunzione si può avere perdita di informazioni:


mancano i dati del dipendente con ID=5 (manca il
dipartimento di assegnazione) e del dipartimento di codice
Pers (senza dipendenti ad esso assegnati).

Come si è anticipato nel Capitolo 3, gli strumenti per recuperare le informazioni sulle righe che
non hanno corrispondenti nella congiunzione sono i join esterni e, in particolare, il left join che
è presentato a fine paragrafo.

• Interrogazioni in SQL
Dopo aver visto come si rappresentano nel linguaggio SQL le operazioni fondamentali del
modello relazionale, impariamo a costruire interrogazioni composte da una sequenza di opera-
zioni relazionali.

Esempio
Per ottenere l’elenco dei dipendenti che lavorano in un dipartimento con sede a Roma, con
cognome, nome e descrizione del dipartimento, occorre dapprima operare una selezione su
Dipartimenti per Sede = ‘Roma’; poi si deve effettuare una congiunzione della tabella ottenuta
con la tabella Impiegati e, infine, applicare una proiezione sugli attributi Cognome, Nome, Descri-
zione sulla nuova tabella risultante.

1. σP Dipartimenti Temp1=Selezione di Dipartimenti per Sede = ‘Roma’


2. Temp1PK ImpiegatiFK Temp2=Congiunzione di Temp1 su Codice e Impiegati
su Dipartimento
3. ΠL Temp2 Proiezione di Temp2 su Cognome, Nome, Descrizione

SELECT Cognome, Nome, Descrizione


FROM Impiegati, Dipartimenti Dipartimento=Codice è la clausola di congiunzione
WHERE Dipartimento=Codice AND Sede=‘Roma’ è la clausola di selezione.
Sede = 'Roma';

SELECT Impiegati.Cognome, Impiegati.Nome, Dipartimenti.Descrizione


FROM Impiegati, Dipartimenti
Per evitare ogni ambiguità
WHERE Impiegati.Dipartimento = Dipartimenti.Codice AND
si può precisare il nome
Dipartimenti.Sede = 'Roma';
delle tabelle oltre a quello
degli attributi.

Per semplificare la scrittura del comando Select è possibile fare ricorso agli alias per il nome della
tabella, specificando dopo il nome originale della tabella la parola AS seguita dal nuovo nome.

220 5. IL LINGUAGGIO SQL © Istituto Italiano Edizioni Atlas


Si potrebbe, per esempio, indicare la tabella Impiegati con I e la tabella Dipartimenti con D,
limitando il numero di caratteri da digitare, scrivendo così comandi più compatti, più semplici da
leggere ma ugualmente significativi.
La precedente interrogazione, scritta nelle due diverse sintassi introdotte, è riportata di seguito.

SELECT I.Cognome, I.Nome, D.Descrizione Importante: se si definisce una alias


FROM Impiegati AS I, Dipartimenti AS D nella clausola From, non si può usare
WHERE I.Dipartimento = D.Codice AND il nome originale della tabella.
D.Sede = 'Roma';
AS è opzionale nella
ridenominazione di tabelle.
SELECT I.Cognome, I.Nome, D.Descrizione
FROM Impiegati I INNER JOIN Dipartimenti D ON I.Dipartimento = D.Codice
WHERE D.Sede = 'Roma';

Risulta evidente la maggior chiarezza dell’ultima interrogazione rispetto alle precedenti: la sin-
tassi adottata da Access ha il pregio di separare nettamente la condizione di congiunzione, che
viene espressa nella parte From dell’interrogazione, dalle condizioni di selezione, che sono
espresse nella parte Where della query.
Per sopperire alla minor chiarezza delle interrogazioni scritte nella versione base di SQL è
opportuno scrivere la parte Where dell’interrogazione su più righe, come nell’esempio preceden-
te, riportando prima le condizioni per la congiunzione delle tabelle e poi le condizioni che
esprimono la selezione.

Dagli esempi precedenti si può osservare come nel linguaggio SQL con poche parole di codice
sia possibile estrarre da una base di dati tutte le informazioni che si desiderano. Le stesse
operazioni, formulate attraverso le istruzioni di un linguaggio di programmazione tradizionale,
richiederebbero un elevato numero di righe di codice, oltre che lunghi processi di ricerca sui file
e di confronti tra i campi dei record.

• Il self-join si attua quando si congiunge una tabella con se stessa. Come si è osservato nel
Capitolo 3, questa esigenza si presenta nel caso delle associazioni ricorsive, per esempio nel caso
di una gerarchia aziendale o della distinta base che descrive oggetti composti da diverse parti.

Esempio
Mostriamo come si possa realizzare un self-join su una tabella. Si consideri l’associazione
esistente tra l’entità Oggetto di attributi: ID, Descrizione e Qta, e le sue parti (che sono altri
oggetti). La tabella che rappresenta gli oggetti e tale associazione ha lo schema sotto riportato
assieme a un’istanza della tabella Oggetti.

Oggetti (ID, Descrizione, Qta, ComponenteDi)

Il bottone (ID=4 ) è una


componente della camicia
(ID=1 ) e in una camicia
ci sono 10 bottoni.

L’oggetto camicia è composto da:


1 colletto, 2 maniche, 10 bottoni,
1 taschino e altri oggetti.

© Istituto Italiano Edizioni Atlas 5. IL LINGUAGGIO SQL 221


Se si vogliono ottenere le informazioni delle diverse parti che compongono un oggetto, per
esempio la camicia, bisogna congiungere la tabella Oggetti con se stessa, cioè operare un self-
join. Per esprimere la condizione che una riga di Oggetti deve essere abbinata a una riga, sempre
di Oggetti, con il valore di ID uguale a quello di ComponenteDi nell’altra, occorre usare gli alias
per il nome della tabella.

AS Parti AS Composto

La ridenominazione di Oggetti precisa


il differente ruolo giocato dalla tabella
Oggetti nell’associazione ricorsiva.

L’interrogazione SQL che elenca le parti che compongono la camicia è mostrata in figura assieme
alla tabella visualizzata al momento dell’esecuzione della query.

SELECT Parti.Descrizione AS Componente,


Parti.Qta,
Composto.Descrizione AS Prodotto
FROM Oggetti AS Parti, Oggetti AS Composto
WHERE Parti.ComponenteDi = Composto.ID AND
Composto.Descrizione = 'Camicia';

• I join esterni: oltre ai join interni il linguaggio SQL permette di costruire dei join che includono
nella congiunzione anche quelle righe di una delle due tabelle che non hanno corrispondenti
nell’altra. Si tratta dei join esterni e, come si è già detto, corrispondono alle operazioni di left
join, right join, full join dell’algebra relazionale.

Tra i join esterni consideriamo il left join e mostriamo la sua utilità nella soluzione di un tipico
problema di assenza: elencare i dipartimenti che non hanno dipendenti loro assegnati. Per farlo
congiungiamo la tabella Dipartimenti e la tabella Impiegati con un left join.

Il left join include comunque tutte le righe della tabella a


sinistra (Dipartimenti) anche in mancanza di record associati.
La riga del dipartimento Personale è stata completata con
valori nulli nei campi Nome e Cognome perché non ci sono
dipendenti ad esso assegnati.

SELECT Descrizione, Nome, Cognome


FROM Dipartimenti D LEFT JOIN Impiegati I ON
D.Codice = I.Dipartimento;

SELECT Descrizione
FROM Dipartimenti D LEFT JOIN Impiegati I ON
D.Codice = I.Dipartimento
I dipartimenti senza impiegati si riconoscono per la
WHERE Cognome IS NULL;
presenza di valori nulli nei campi che provengono da
Impiegati. Per il controllo si usa il predicato IS NULL.

4 TEST 5.1 pag. 247 ESERCIZI da 3 a 12 pag. 249-250 e da 42 a 49 pag. 251

CONTENUTI DIGITALI INTEGRATIVI


1. Tipi di join esterni e operazioni insiemistiche

222 5. IL LINGUAGGIO SQL © Istituto Italiano Edizioni Atlas


8 Le funzioni di aggregazione
Nel comando Select si possono usare funzioni predefinite che agiscono sui valori contenuti in
insiemi di righe di una tabella e che, per questo motivo, si chiamano funzioni di aggregazione.
Le funzioni di aggregazione agiscono sui valori di una colonna e restituiscono un solo valore
come, per esempio, il massimo o il minimo dei valori considerati. Le righe considerate per
l’aggregazione sono quelle prodotte dall’interrogazione e quindi, in presenza di una clausola
Where, sono le sole righe che soddisfano la condizione specificata.
• Le funzioni di aggregazione possono comparire solo nelle clausole Select ed Having (che sarà
spiegata nel riquadro alla fine del prossimo paragrafo).
• La presenza di una funzione di aggregazione nella clausola Select provoca un’intestazione che
dipende dall’implementazione di SQL. Nel caso di Access l’intestazione è del tipo EXPR1000,
EXPR1001, ecc.

• Funzione COUNT
La funzione COUNT conta il numero di occorrenze selezionate dall’interrogazione. La sintassi del
linguaggio SQL richiede di specificare come argomento della funzione il nome di un attributo
oppure il carattere * (asterisco). Nel primo caso sono conteggiati i valori non nulli nella colonna
considerata; nel secondo caso, la funzione Count(*) calcola il numero di righe nella tabella.

SELECT COUNT (*) Conta le righe della tabella Impiegati:


FROM Impiegati; Restituisce 12.

Conta il numero dei dipendenti di Impiegati che


SELECT COUNT (Dipartimento) sono assegnati a un dipartimento. Restituisce
FROM Impiegati; 11 perché non sono considerati i valori nulli.

SELECT COUNT(*)
Conta il numero dei dipendenti residenti a Roma.
FROM Impiegati Restituisce 2.
WHERE Residenza = 'Roma';

SELECT COUNT(*), COUNT(*) AS ResidentiRoma


Con le funzioni di aggregazione è opportuno
FROM Impiegati
rinominare le colonne per evitare la presenza
WHERE Residenza = 'Roma';
di intestazioni poco significative.

• Funzione SUM
La funzione SUM restituisce la somma dei valori contenuti in una colonna, specificata come
argomento della funzione: naturalmente l’attributo utilizzato nel calcolo deve essere di tipo
numerico; i valori nulli sono trascurati dalla funzione Sum.

SELECT SUM (Stipendio) La somma degli stipendi dei dipendenti


FROM Impiegati del dipartimento Amministrazione.
WHERE Dipartimento = 'Amm'; Restituisce 90000.

© Istituto Italiano Edizioni Atlas 5. IL LINGUAGGIO SQL 223


SELECT SUM (Stipendio) AS StipendiAmm, L’ammontare degli stipendi del reparto
SUM (Stipendio*1.03) AS NuoviStipendiAmm Amministrazione e il nuovo totale dopo
FROM Impiegati un loro incremento del 3%.
WHERE Dipartimento = 'Amm';

L’argomento di Sum può


essere un’espressione.

• Funzione AVG
La funzione AVG (dall’inglese average = media), calcola la media dei valori (numerici) contenuti
in una colonna di una tabella. L’argomento della funzione può essere un’espressione aritmetica
anziché il nome di un attributo. La media calcolata dalla funzione Avg è la media aritmetica, cioè
la somma dei valori diviso il numero dei valori. La funzione Avg non include nel calcolo i valori
Null presenti nella colonna.

SELECT AVG(Stipendio)
Calcola lo stipendio medio dei
FROM Impiegati, Dipartimenti
dipendenti che lavorano a Torino.
WHERE Dipartimento = Codice AND Restituisce 46916,67.
Sede = 'Torino';

• Funzioni MIN e MAX


Le funzioni MIN e MAX restituiscono rispettivamente il valore minimo e il valore massimo tra
quelli assunti dalla colonna specificata come argomento della funzione; le funzioni Min e Max
consentono di determinare i valori minimi e massimi anche per campi di tipo carattere. Anche le
funzioni Min e Max ignorano i campi con valore Null e possono avere come argomento un’espres-
sione anziché il nome di un attributo.

SELECT MIN(Stipendio),
Calcola lo stipendio minimo e massimo dei dipendenti.
MAX(Stipendio)
Restituisce 25000 e 85000.
FROM Impiegati;

SELECT MIN(Cognome),
Primo e ultimo cognome (secondo l’ordine alfabetico) dei dipendenti.
MAX(Cognome) Restituisce Bianco e Volpi.
FROM Impiegati;

9 Ordinamenti e raggruppamenti
Nel comando Select si può inserire la clausola ORDER BY per ottenere i risultati di un’interroga-
zione ordinati secondo i valori contenuti in una o più colonne, che vengono specificate di seguito
alla clausola Order By. L’indicazione delle colonne da considerare nell’ordinamento avviene pre-
cisando il nome della colonna oppure la posizione che essa occupa nella lista che segue la parola
Select: 1 per la prima posizione, 2 per la seconda, e così via.
L’ordinamento può essere crescente (le stringhe dalla A alla Z e i numeri dal minore al maggiore)
oppure decrescente (le stringhe dalla Z alla A e i numeri dal maggiore al minore): i due tipi di
ordinamento sono precisati usando le parole chiave ASC per crescente e DESC per decrescente.
L’ordinamento è crescente per default e quindi va specificata la parola Desc solo se si desidera
l’ordinamento decrescente.

224 5. IL LINGUAGGIO SQL © Istituto Italiano Edizioni Atlas


Negli ordinamenti il valore Null compare, di norma, all’inizio delle sequenze crescenti e alla fine
delle sequenze decrescenti.
La clausola Order By, se presente, deve essere l’ultimo elemento di un comando Select.

Esempio

SELECT Cognome, Nome, Residenza


Elenco alfabetico dei dipendenti per Cognome
FROM Impiegati
e, a parità di cognome, per Nome.
ORDER BY Cognome, Nome;

SELECT Cognome, Stipendio


Elenco dei dipendenti in ordine decrescente di stipendio
FROM Impiegati e, a parità di stipendio, in ordine (crescente) di cognome.
ORDER BY Stipendio DESC, Cognome;

Si consideri una tabella di fatture che contiene, per ogni fattura, la descrizione del prodotto, il
suo prezzo unitario e la quantità ordinata.

Elenco ordinato per valori


1 2 3 4 decrescenti dell’espressione:
SELECT NomeProdotto, PrezUnit, Qta, PrezUnit*Qta PrezUnit*Qta (campo 4 della
FROM Fatture clausola Select).
ORDER BY 4 DESC; Forma sconsigliata perché
non simbolica.

SELECT NomeProdotto, PrezUnit, Qta, PrezUnit*Qta AS Totale


FROM Fatture
ORDER BY Totale DESC; Forma raccomandata perché simbolica.
Non supportata da Access.

SELECT NomeProdotto, PrezUnit, Qta, PrezUnit*Qta AS Totale


FROM Fatture
ORDER BY PrezUnit*Qta DESC; Forma raccomandata con Access.

Con le funzioni di aggregazione si condensano le informazioni di una tabella in un solo valore


come, per esempio, la somma degli stipendi di tutti i dipendenti. Spesso è però utile sintetizzare
i valori per classi omogenee, secondo opportuni criteri di raggruppamento, per esempio per
produrre la somme parziali degli stipendi nei diversi dipartimenti.

La clausola GROUP BY ha questo scopo, in quanto permette di raggruppare un insieme di righe


aventi lo stesso valore nelle colonne indicate dalla clausola. L’opzione produce una riga di risultati
per ogni raggruppamento. Se nel comando viene inserita una funzione di aggregazione, come
Sum o Count, per ciascuna riga della tabella risultante viene prodotto un valore di raggruppa-
mento. I valori Null sono raggruppati, ma non vengono valutati da nessuna delle funzioni di
aggregazione ad eccezione di Count(*).

Importante: con i raggruppamenti nella clausola Select possono comparire


solo i campi presenti in Group By e funzioni di aggregazione.

SELECT Dipartimento,
COUNT(ID) AS Dipendenti,
Elenco dei dipartimenti con la somma degli
SUM(Stipendio) AS Stipendi
stupendi e il numero di addetti per dipartimento.
FROM Impiegati
GROUP BY Dipartimento;

© Istituto Italiano Edizioni Atlas 5. IL LINGUAGGIO SQL 225


L’interrogazione è eseguita secondo i due passi indicati in figura.

1
Le righe sono
raggruppate per
dipartimento.

2
Le funzioni di aggrega-
zione sono applicate
separatamente ai singoli
raggruppamenti.

Se nell’elenco si desidera che compaia, invece del codice, il nome per esteso del dipartimento,
bisogna effettuare il raggruppamento sul campo Descrizione della tabella Dipartimenti.

SELECT Descrizione,
COUNT(*) AS Dipendenti, Nell’elenco sono esclusi i dipendenti
che non sono inquadrati in alcun
SUM(Stipendio) AS Stipendi
dipartimento (come il dipendente
FROM Impiegati, Dipartimenti
con ID =5 dell’esempio) che
WHERE Impiegati.Dipartimento = Dipartimenti.Codice
scompaiono nella congiunzione.
GROUP BY Descrizione;

Condizioni sui raggruppamenti


La struttura del comando Select con raggruppamenti può essere ulteriormente ampliata con
la clausola HAVING con la quale è possibile sottoporre al controllo di una o più condizioni
i gruppi creati con la clausola Group by. La condizione scritta dopo Having in genere controlla
il valore restituito dalle funzioni di aggregazione (Count, Sum, Avg, Min, Max).
Si noti che la clausola Having deve essere usata insieme a Group By: dopo che Group By ha
formato i raggruppamenti di righe, Having serve a visualizzare i soli raggruppamenti che
soddisfano alle condizioni scritte accanto a Having.

SELECT Dipartimento, COUNT(ID) AS Dipendenti, SUM(Stipendio) AS Stipendi


FROM Impiegati
GROUP BY Dipartimento Numero degli addetti e la somma degli stipendi
HAVING COUNT(ID) > 2; per i dipartimenti con più di 2 dipendenti.

Se l’istruzione Select contiene la clausola Where, i valori vengono raggruppati dopo aver
operato la selezione sulle righe che rispettano le condizioni scritte accanto a Where.

SELECT Descrizione, Numero degli addetti e somma degli stipendi per


COUNT(ID) AS Dipendenti, i dipartimenti di Torino con più di 1 addetto.
SUM(Stipendio) AS Stipendi
FROM Dipartimento D INNER JOIN Impiegati I ON
D.Codice = I.Dipartimento
WHERE Sede = 'Torino'
GROUP BY Descrizione WHERE:
condizioni
HAVING COUNT(ID) > 1;
sulle righe
delle tabelle.
HAVING: condizioni sui raggruppamenti.

226 5. IL LINGUAGGIO SQL © Istituto Italiano Edizioni Atlas


Per realizzare l’ultima interrogazione con Access in modalità QBE bisogna trovare il modo di
esprimere nella griglia posta nella parte inferiore della QBE sia le condizioni sui raggruppa-
menti (in Having) sia le condizioni sulle righe (clausola Where).
Operando come descritto nel Capitolo 4, si fa clic sul pulsante Totali per attivare la riga
Formula nella griglia QBE e si definiscono nei diversi campi raggruppamenti, conteggi,
somme in base alle richieste del problema.

Il segno di spunta nella casella


Mostra è deselezionato
automaticamente.
2

Selezionare Dove
Le condizioni scritte nella nel menu a discesa
3
riga Criteri della QBE Le condizioni scritte nella riga della riga Formula.
sono interpretate come Criteri della QBE sono 1
condizioni sui raggruppa- interpretate come condizioni
menti: clausola Having. sulle righe: clausola Where.

Sintetizziamo in un unico quadro le diverse clausole che possono apparire nel comando Select:

SELECT Elenco espressioni da mostrare


FROM Tabelle da cui estrarre le righe
WHERE Condizioni sulle righe estratte
GROUP BY Campi da considerare per i raggruppamenti
HAVING Condizioni sui raggruppamenti
ORDER BY Ordinamenti sulle espressioni elencate nella clausola SELECT

È opportuno fare le seguenti precisazioni:


• Si possono scrivere comandi del tipo: Select Now(); oppure Select 3*4; nei quali compare
la sola clausola Select.
• Per estrarre dati da una tabella le uniche clausole che devono comparire obbligatoriamente
sono Select e From mentre le altre sono facoltative.
• Le clausole utilizzate devono essere elencate rispettando l’ordine del precedente elenco:
Select deve precedere From, ..., Having deve precedere Order by.
• Le interrogazioni che si possono costruire con le operazioni relazionali si esprimono con
le sole clausole Select, From e Where.
• Il DBMS esegue il comando elaborando le clausole nel seguente ordine:
From  Where  Group by  Having  Select  Order by

CONTENUTI DIGITALI INTEGRATIVI


2. Query di comando e query di servizio in Access

© Istituto Italiano Edizioni Atlas 5. IL LINGUAGGIO SQL 227