Lezione del modulo 7 SQL e database del giorno

Lezione del modulo 7 SQL e database del giorno 04/05/2006
tot. ore 3
Lo Standard SQL
Il linguaggio SQL è un linguaggio non procedurale (o di tipo dichiarativo), divenuto, ormai da
tempo, il linguaggio standard per creare, manipolare e interrogare basi di dati relazionali.
Il linguaggio SQL assolve alle funzioni di:
• DDL (Data Definition Language), che prevede le istruzioni per definire la struttura delle
relazioni della base dei dati. Serve, quindi, a creare tabelle, vincoli, viste, ecc.
• DML (Data Manipulation Language), che prevede le istruzioni per manipolare i dati
contenuti nelle diverse tabelle. In particolare, permette inserimenti, cancellazioni e
modifiche delle righe delle tabelle nonché consente di effettuare interrogazioni sulle basi di
dati.
• DCL (Data Control Language), che prevede istruzioni per controllare il modo in cui le
operazioni vengono eseguite. Consente di gestire il controllo degli accessi per più utenti e i
permessi per gli utenti autorizzati.
SQL può essere usato in:
• Modalità stand-alone o sé stante;
può essere classificato come interactive query language (linguaggio di interrogazione interattivo). I comandi
possono essere inviati al S.O. in modo interattivo o batch. Si usa una interfaccia grafica che guida l’utente.
Per eseguire ogni istruzione viene invocato l’interprete SQL. Le interrogazioni complesse vengono composte
sfruttando le operazioni dell’algebra relazionale, come trattati nelle precedenti dispense, ottenendo come
risultato sempre una relazione.
•
Modalità embedded o linguaggio ospite.
In questo caso, dato che il linguaggio ospite può trattare le tuple anche singolarmente è possibile utilizzare
comandi SQL all’interno di istruzioni C, JAVA o C++, che vengono chiamati, in questo caso, linguaggi ospite.
Un programma scritto in un linguaggio ospite compilato (che incorpora istruzioni SQL al suo interno) subirà
un primo processo di precompilazione seguito da una vera e propria compilazione.
Identificatori e tipi di dati
SQL non è un linguaggio case sensitive. Generalmente ogni istruzione si conclude con ; (punto e
virgola).
Ogni identificatore utilizzato per il nome della tabella e dei suoi attributi deve:
• Avere lunghezza massima di 18 caratteri
• Iniziare con una lettera
• Contenere come unico carattere speciale l’underscore (_)
Nella terminologia SQL le relazioni sono chiamate tabelle, le tuple righe o registrazioni e gli
attributi sono le colonne delle tabelle.
Per riferirsi a un attributo di una tabella la sintassi è la seguente
<nometabella>.<nomeattributo>
Le costanti stringa sono rappresentabili utilizzando gli apici (‘ ‘) o doppi apici (“
Gli operatori utilizzati nelle espressioni sono:
• Aritmetici +, - , / , *
• Relazionali < , > , <= , >= , <>
• Logici
AND , OR, NOT
“)
I tipi di dato utilizzabili per gli attributi sono qui riassunti:
tipo
Descrizione
CHARACTER O CHAR
CHARACTER(n) o CHAR(n)
CHARACTER VARYNG(n)
VARCHAR(n)
BIT
BIT(n)
BIT VARYNG(n)
INTEGER o INT
INTEGER(n) o INT(n)
SMALLINT
DECIMAL(p,d) o DEC(p,d)
REAL
FLOAT
FLOAT(p)
DOUBLE PRECISION
DATE
TIME
TIMESTAMP
o
Singolo carattere
Stringa di caratteri di lunghezza fissa
pari a n caratteri
Stringa di caratteri di lunghezza
variabile con lunghezza massima pari a
n
Singolo bit; tipo booleano
Esempi e/o Range di
variabilità
“C” oppure “5”
n varia da 1 a 15000
esempio “ax005”
VARCHAR(5)
“ER567”
0 corrisponde a false
1 corrisponde a true
Stringa di bit di lunghezza fissa pari a n
BIT(5)
“00110”
String di bit di lunghezza variabile BIT VARYNG(7)
avente lunghezza massima pari a n
“0011010”
Numero intero con precisione superiore -2147483648 a +2147483647
a SMALLINT che generalmente occupa
4 byte ma dipende dall’implementazione
Numero intero con precisione n (numero
massimo di cifre che il numero può
contenere)
Numero intero con precisione inferiore a
INTEGER (occupa 2 byte di memoria)
Numero reale in fixed point con un
numero massimo di cifre prima del
punto decimale pari a p e un numero
massimo di cifre dopo il punto decimale
pari a d. Le dimensioni massime di p e d
sono definite dall’implementazione.
Numero reale in floating point con
precisione definita dall’implementazione
Generalmente vale 7 per la mantissa
Numero reale in floating point con
precisione definita dall’implementazione
Generalmente vale 15 per la mantissa
Numero reale in floating point con
precisione p per la mantissa
Numero reale in floating point con
precisione per la mantissa doppia
rispetto alla precisione di un FLOAT
Data nel formato “AAAA/MM/GG”
Oppure “AAAA-MM-GG”
Ora nel formato ora, minuti, secondi e
millisecondi.
Data e orario nel formato anno, mese,
giorno, ora, minuti, secondi e
millisecondi
INT(5)
-32768
a
+32767
DECIMAL(6,2)
100.3 o +0.7
o -.3
Da 1E-38 a 1E+38
10E4 +24.7E-3 -7.897E+12
Da 1E-38 a 1E+38
10E4 +24.7E-3 -7.897E+12
P varia da 1 a 45
L’esponente da -127 a +128
“2006/04/30”
“2006-04-30”
“10:34:25:42”
“2000/04/30 10:34:25:42”
Si ricordi che questi sono i tipi di dati della versione ISO 9075 e che in alcune versioni tali tipi
sono differenti. Ecco perché di seguito ho riportato le tabelle dei tipi che si riferisco a MySQL e ad
ACCESS.
MySQL
Tipo
BIGINT
INTEGER
SMALLINT
TINYINT
DOUBLE
FLOAT
DECIMAL
DATE
TIME
DATETIME
YEAR
CHARACTER
VARCHAR
TEXT
MEDIUMTEXT
BLOB
MEDIUM BLOB
LONG BLOB
Descrizione
Intero lunghissimo
Intero lungo
Intero
Intero ridotto
Reale a doppia precisione
Reale a singola precisione
Decimale memorizzato come stringa
Data in formato AAAA-MM-GG
Orario in formato HH:MM:SS
Data con ora
Anno
Stringa a lunghezza fissa
Stringa a lunghezza variabile
Campo testo a lunghezza fissa
Campo testo (memo)
Immagini jpeg, bmp, gif oppure file
binary in esadecimale o di testo
Dimensione max/formato
INTERI
REALI
DATA
STRINGA
OGGETTI
-263 a +263-1
-231 a +231-1
-32768 a +32767
-128 a +127
±2.225*10-308 a ±1.798*10308
±1.176*10-38 a ±3.403*1038
±2.225*10-308 a ±1.798*10308
Dal 1000-01-01 al 9999-12-31
HH:MM:SS
aaaa-mm-gg hh:mm:ss
AAAA
Da 0 a 255 caratteri
Da 0 a 255 caratteri
Da 0 a 65535 caratteri
16 mb di caratteri – 1
Fino a 64 Kb
Fino a 16 mb
Circa 4 Gb
ACCESS
Tipo
BOOLEAN
BYTE
INTEGER
LONG
Descrizione
Un bit memorizzato in 1 byte
Intero ridotto
Intero
Intero Lungo 4 byte
DOUBLE
Reale a doppia precisione a 8 byte
SINGLE
Reale a singola precisione a 4 byte
VARIANT
Con numeri a 16 byte
CURRENCY
Decimale a 8 byte per valuta
DATE
STRING
MEMO
VARIANT
Data 8 byte
Stringa a lunghezza fissa
Campo testo a lunghezza fissa
Con caratteri
Immagini jpeg, bmp, gif oppure file
binary in esadecimale o di testo
OBJECT
Dimensione max/formato
INTERI
REALI
DATA
STRINGA
OGGETTI
0 (false) oppure 1 (true)
Da 0 a 255
-32768 a +32767
-2147483648 a +2147483647
-1,79E308 a -14,94E-324 per negativi
+4,94E-324 a 1,79E308 per positivi
-3,40E38 a -1,40E-45 per negativi
1,40E-45 a 3,40E38 per positivi
Vedi DOUBLE
Da -922.337.203.685.477,5808
A +922.337.203.685.477,5807
Dal 01/01/100 al 31/12/9999
Da 0 a 255 caratteri
Da 0 a 65535 caratteri
22 + lunghezza
4 byte
Istruzioni DDL di SQL
I comandi di DDL creano e modificano lo schema di una base di dati:
1. Creazione di un database
CREATE DATABASE [IF NOT EXISTS] <nomedatabase>
[[DEFAULT] CHARACTER SET <NOMESETCARATTERI>[,…]]
Questo comando crea un database di nome <nomedatabase> solo se non esiste già che è compatibile
con il set di caratteri <NOMESETCARATTERI> . Lo standard è latin1. Le caratteristiche del
database vengono salvate nel file db.opt.
MYSQL: il comando è identico
ACCESS: i database devono essere creati all’interno dell’ambiente GUI
2. Cancellazione di un database
DROP DATABASE [IF EXISTS] <nomedatabase>
Il comando seguente mi permette di eliminare definitivamente un database.
MYSQL: il comando è identico
ACCESS: i database devono essere eliminati dal file system.
3. Creare una tabella
MYSQL:
CREATE [IF NOT EXISTS] TABLE <NOMETABELLA>
({nomecampo tipo [(lunghezza 1 )] [UNSIGNED 2 ] [ZEROFILL 3 ] [NOT NULL | NULL 4 ]
[DEFAULT valoredidefault 5 ] [AUTO_INCREMENT 6 ] [[PRIMARY] KEY] [UNIQUE]}[,…]
[PRIMARY KEY (nomecampo)]
[INDEX [nomeindice] ((nomecampo) ]
[UNIQUE [index] ]
[FOREIGN KEY [nomeindice] ] )
[TYPE=[HEAP | ISAM | InnoDB | MYISAM]];
HEAP: è una tabella temporanea, in cui I dati risiedono direttamente in memoria. Non deve essere utilizzata per
memorizzare i dati in modo permanente in quanto ad ogni riavvio di MySQL server tutti i dati vengono persi. I tempi di
accesso sono più bassi rispetto alle tabelle MYISAM. Non possiedono il tipo Text e Blob.
InnoDB: è un tipo di tabella che consente di operare con transazioni e foreign Key non supportate dalle altre tabelle. Il
motore di gestione delle tabelle InnoDB mantiene le tabelle entro l’area tabellare che può essere composta anche da diversi
file. La dimensione massima è comunque di 64 Tb.
MYISAM: è il tipo di tabella di default. Se creata in modo statico i record sono di lunghezza prefissata. Sono assicurate
maggiore velocità di accesso e maggiore sicurezza in caso di crash. Se create in modo dinamico ogni record occupa solo lo
spazio necessario. Successivi update possono portare alla frammentazione in più pezzi del medesimo archivio. Se create in
modo compresso viene ridotto lo spazio occupato dai file .MYI e .MYD. Le tabelle ottenute sono in solo lettura. La
dimensione massima è di 4 Gb.
1
Determina la lunghezza massima del campo.
I numeri possono essere con segno o senza segno
3
Riempie di zeri tutta la lunghezza del campo. Usato per i codici.
4
Determina se il campo può essere lasciato vuoto (NULL) oppure no (NOT NULL).
5
Determina quale valore o stringa deve contenere il campo prima che avvenga l’immissione di un nuovo dato.
6
È un campo numerico il cui valore viene incrementato di 1 ad ogni nuovo record. A differenza di Access il valore può
essere reinserito se il record viene eliminato.
2
ACCESS:
CREATE TABLE <NOMETABELLA>
({nomecampo tipo [(lunghezza*)] [NOT NULL][WITH COMPRESSION]
[[PRIMARY] KEY] [UNIQUE] }
[,…]
[PRIMARY KEY (nomecampo)]
[[UNIQUE] INDEX [nomeindice] ((nomecampo) ]
[FOREIGN KEY [nomeindice] ] );
* in Access non è possible indicare, nella creazione di una tabella, la lunghezza di un campo numerico.
4. I vincoli di integrità
Nella definizione di una tabella sono presenti vincoli:
• Per un singolo attributo;
Impostano limitazioni da specificare su singolo attributo.
NOT NULL il corrispondente attributo deve avere necessariamente un valore e non può non
rimanere non specificato.
DEFAULT assegna all’attributo il valore di default.
• Per un gruppo di attributi detti anche vincoli di ennupla
Impostano limitazioni da specificare sui valori di più attributi.
PRIMARY KEY indica le colonne che fanno parte della chiave primaria.
UNIQUE indica che i valori degli attributi specificati negli attributi (che non formano una
chiave primaria) devono essere distinti all’interno della tabella (formano una chiave
candidata).
• Per l’integrità referenziale.
Questi vincoli permettono di creare un legame permanente tra diverse tabelle. È un vincolo
mediante un dato presente in un’altra tabella. Il vincolo alla tabella esterna viene detto
FOREIGN.
MYSQL: questi vincoli posso essere attivati soltanto sulle tabelle di tipo InnoDB. Se si
utilizza una tabella MYISAM, il codice viene letto senza errori ma modificando la tabella
l’integrità referenziale non viene verificata.
…
[INDEX (<nomecampotabellainterna>)],
[FOREIGN KEY ((<nomecampotabellainterna>)
REFERENCES <nometabellamadre> (<nomecampochiaveprimaria>)]
In questo caso si definiscono due tabelle poste in relazione tra loro. La tabella madre è in
relazione con la tabella figlia tramite un campo, chiave primaria nella madre e foreign key
nella figlia.
ACCESS: Access permette di eseguire questa operazione tramite l’ambiente GUI, che
chiama relazioni.
…
<nomecampotabellainterna> tipo NOT NULL CONSTRAINT m REFERENCES
<nometabellamadre> (<nomecampochiaveprimaria>)]
Ma impostare i campi all’integrità referenziale significa anche prevedere cosa succede se il record
della tabella madre dovesse essere cancellato.
Le operazioni da eseguire possono essere introdotti in base ai seguenti eventi:
• Aggiornamento (UPDATE)
• Cancellazioni (DELETE)
Le possibili reazioni a questi eventi sono:
• CASCADE propaga la modifica anche alla tabella figlia
• SET NULL annulla l’attributo portandolo al valore NULL
• SET DEFAULT assegna all’attributo il valore di default
• RESTRICT impedisce che la modifica possa avvenire
…
[INDEX (<nomecampotabellainterna>)],
[FOREIGN KEY ((<nomecampotabellainterna>)
REFERENCES <nometabellamadre> (<nomecampochiaveprimaria>)]
[ON {DELETE | UPDATE}
{CASCADE | SET NULL | SET DEFAULT | RESTRICT}]
MYSQL:
Esempio:
CREATE TABLE mansioni
( id_mansione INT(4) DEFAULT ‘0’ NOT NULL PRIMARY KEY,
Nome CHAR(20) NOT NULL) TYPE=INNODB;
CREATE TABLE dipendenti
(matricola CHAR(6) DEFAULT ‘0’ NOT NULL PRIMARY KEY,
nome CHAR(20) NOT NULL,
cognome CHAR(20) NOT NULL,
mansione INT(4) NOT NULL,
INDEX (mansione),
FOREIGN KEY (mansione) REFERENCES mansioni(id_mansione) ON DELETE CASCADE,
UNIQUE(nome,cognome) ) TYPE=INNODB;
Nel caso in cui si dovesse cancellare il record id_mansione = 1
Id_mansione
1
2
3
Nome
matricola
Nome
Cognome
mansione
Impiegato
Quadro
Operaio
12345
12355
12366
12377
12388
Alfa
Beta
Delta
Gamma
Teta
Neri
Verdi
Rossi
Bianchi
Gialli
1
3
1
2
1
matricola
Nome
Cognome
mansione
12355
12377
Beta
Gamma
Verdi
Bianchi
3
2
Il risultato sarebbe:
CREATE TABLE mansioni
( id_mansione INT(4) DEFAULT ‘0’ NOT NULL PRIMARY KEY,
Nome CHAR(20) NOT NULL) TYPE=INNODB;
CREATE TABLE dipendenti
(matricola CHAR(6) DEFAULT ‘0’ NOT NULL PRIMARY KEY,
nome CHAR(20) NOT NULL,
cognome CHAR(20) NOT NULL,
mansione INT(4) NOT NULL,
INDEX (mansione),
FOREIGN KEY (mansione) REFERENCES mansioni(id_mansione) ON DELETE SET DEFAULT,
UNIQUE(nome,cognome) ) TYPE=INNODB;
Nel caso in cui si dovesse cancellare il record id_mansione = 1
matricola
Nome
Cognome
mansione
12345
12355
12366
12377
12388
Alfa
Beta
Delta
Gamma
Teta
Neri
Verdi
Rossi
Bianchi
Gialli
0
3
0
2
0
CREATE TABLE mansioni
( id_mansione INT(4) DEFAULT ‘0’ NOT NULL PRIMARY KEY,
Nome CHAR(20) NOT NULL) TYPE=INNODB;
CREATE TABLE dipendenti
(matricola CHAR(6) DEFAULT ‘0’ NOT NULL PRIMARY KEY,
nome CHAR(20) NOT NULL,
cognome CHAR(20) NOT NULL,
mansione INT(4) NOT NULL,
INDEX (mansione),
FOREIGN KEY (mansione) REFERENCES mansioni(id_mansione) ON DELETE SET NULL,
UNIQUE(nome,cognome) ) TYPE=INNODB;
Nel caso in cui si dovesse cancellare il record id_mansione = 1
matricola
Nome
Cognome
mansione
12345
12355
12366
12377
12388
Alfa
Beta
Delta
Gamma
Teta
Neri
Verdi
Rossi
Bianchi
Gialli
Null
3
Null
2
Null
CREATE TABLE mansioni
( id_mansione INT(4) DEFAULT ‘0’ NOT NULL PRIMARY KEY,
Nome CHAR(20) NOT NULL) TYPE=INNODB;
CREATE TABLE dipendenti
(matricola CHAR(6) DEFAULT ‘0’ NOT NULL PRIMARY KEY,
nome CHAR(20) NOT NULL,
cognome CHAR(20) NOT NULL,
mansione INT(4) NOT NULL,
INDEX (mansione),
FOREIGN KEY (mansione) REFERENCES mansioni(id_mansione) ON DELETE RESTRICT,
UNIQUE(nome,cognome) ) TYPE=INNODB;
Nel caso in cui si dovesse cancellare il record id_mansione = 1
Viene segnalato un messaggio di errore
5. La visualizzazione dei database e delle tabelle
Mediante il costrutto SHOW si possono conoscere i nomi dei database esistenti, l’elenco delle
tabelle di un database oppure le caratteristiche di una particolare tabella.
SHOW TABLES | DATABASES | COLUMNS
IN | FROM
Nometabella | nomedatabase
SHOW TABLES IN <nomedatabase>
SHOW COLUMNS FROM <nometabella> IN <nomedatabase>
SHOW DATABASES
visualizza le tabelle in un database
visualizza le colonne e i tipi
visualizza tutti i database
Se si volesse interrogare una tabella senza specificare il database eseguo due istruzioni:
USE <nomedatabase>;
SHOW COLUMNS <nometabella>
6. La modifica dello schema di una tabella.
La struttura di una tabella può essere modificata mediante il costrutto ALTER.
ALTER TABLE <NOMETABELLA> ADD | CHANGE | DROP
[COLUMN] VECCHIONOMECAMPO NUOVONOMECAMPO
[FIRST | AFTER ] NOMECAMPO TIPO
[INDEX NOMEINDICE (NOMECAMPO)]
[PRIMARY KEY NOMEINDICE (NOMECAMPO)
[UNIQUE (NOMECAMPO)]
[FOREIGN KEY NOMEINDICE (NOMECAMPO)]
[REFERENCES…]
ALTER TABLE mansioni ADD COLUMN data_mansione DATA;
aggiunge il campo data_mansione
ALTER TABLE mansioni DROP COLUMN data_mansione;
elimina il campo data_mansione
ALTER TABLE dipendenti ADD INDEX cog_nom(cognome,nome) si crea un indice nella tabella dipendenti
ALTER TABLE mansioni ADD COLUMN nato VARCHAR(20) AFTER data_mansione;
aggiunge il campo nato dopo il campo data_mansione
ALTER TABLE voti CHANGE COLUMN voto voto float(4,1);
aggiorna il tipo del campo voto
7. Cancellazione e modifica di una tabella.
DROP TABLE nometabella
eliminazione di una tabella
ALTER TABLE nomevecchiotabella RENAME nomenuovotabella rinomina una tabella
ACCESS: Access individua sempre una chiave primaria come un indice, assegnandogli un nome;
quindi diversamente da MySQL per l’eliminazione di una chiave primaria o unica si deve far
riferimento al nome associato all’indice.
ALTER TABLE <NOMETABELLA> ADD | DROP
[COLUMN] tipo NOMECAMPO (lunghezza) [CONSTRAINT nome indice]
Istruzioni DML di SQL
Sono operazioni di manipolazione dei dati ossia inserimento di nuovi record e l’eliminazione e la
modifica di tuple.
1. Inserimento di nuove righe
Detta operazione avviene mediante il costrutto INSERT e secondo la seguente sintassi
INSERT INTO <nometabella> (nomi campi) VALUES (lista di valori);
MYSQL: e ACCESS:
Ci sono dei casi in cui il comando INSERT viene usato senza tenere conto di tutte le sue istruzioni.
Caso 1: uso completo
INSERT INTO alunni(matricola,nome,cognome,classe) VALUES (“1234”,”Carlo”,”Rossi”,”3A”);
Caso 2: inserimento del record senza specificare i campi
INSERT INTO alunni VALUES (“1234”,”Carlo”,”Rossi”,”3A”);
Caso 3: inserimento di più alunni senza specificare i campi
INSERT INTO alunni VALUES (“1234”,”Carlo”,”Rossi”,”3A”), (“2678”,”Ugo”,”Bianchi”,”4A”);
Caso 4: inserimento di soli tre campi con rispettivi valori
INSERT INTO alunni(matricola,nome,cognome) VALUES (“1234”,”Aldo”,”Neri”);
Per i campi auto-increment non occorre specificare alcun valore basterà sostituirlo con apici vuoti.
MYSQL: solo in MySQL esiste la possibilità di carica tramite comando dei dati da un file esterno di
formato diverso a quello del database, unica condizione è che il file deve avere il cosiddetto formato
CSV (Comma Separated Values).
LOAD DATA INFILE “nomefile.txt” [REPLACE | IGNORE]
INTO TABLE nometabella
FIELDS TERMINATED BY “simbolo”
LINES TERMINATED BY “simbolo”;
Dove simbolo può essere per FIELDS ( ,
. spazio) e per LINES (\n)
2. Sostituzione delle righe
La sostituzione dei record di una tabella consente di modificare il contenuto di alcuni record
REPLACE
INTO nome tabella (nomi dei campi)
VALUES (elenco valori)
SET nome campo=espressione
È necessario qualora si presenti il caso di sostituire alcuni valori di specificare tutti i campi perché
si rischierebbe di azzerare i dati già presenti.
3. Eliminazione delle righe
Con questo sistema si possono cancellare più di un record.
MYSQL:
DELETE FROM nometabella
WHERE condizione
LIMIT massimo_numeri_di_righe_ammesse;
ACCESS:
DELETE FROM nometabella
WHERE condizione;
Il comando si presenta di una semplicità applicativa, ma si trascura il fatto che alcune tabelle
possono avere dei vincoli di integrità referenziale e la cancellazione di un record dell’entità più
forte potrebbe procurare i seguenti problemi:
a) se nello schema il vincolo è RESTRICT l’eliminazione viene impedita
b) se nello schema il vincolo è SET NULL l’eliminazione viene consentita ed i valori della
tabella figlia diventa NULL
c) se nello schema il vincolo è CASCADE l’eliminazione è possibile e nella tabella figlia
vengono cancellate tutti i record
d) se nello schema il vincolo è SET DEFAULT l’eliminazione viene consentita ed i valori della
tabella figlia diventano di default.
4. Aggiornamento delle righe
Si modifica il contenuto di uno o più record della tabella.
UPDATE nometabella
SET nomecampo= valore o espressione
WHERE condizione;
Istruzioni QL di SQL
L’interrogazione di un database è permessa tramite il costrutto SELECT. Le tre operazioni che tale
costrutto esprime sono le seguenti:
• Selezione tramite una condizione WHERE
• Proiezione tramite i campi che si vogliono estrarre
• Congiunzione tramite i costrutti JOIN oppure mediante la clausola WHERE
Il comando SELECT serve per estrarre dati da una tabella, in pratica vengono estratte tutte e solo le
righe da una tabella che soddisfano una certa condizione.
Sintassi (la sintassi qui data è ovviamente incompleta e semplificata):
SELECT {Campo1, Campo2, ...}
FROM {Tabella 1}
WHERE {Condizione1 AND|OR Condizione2 AND|OR ...}
Es: Sia la tabella Anagrafica
Cognome
Verdi
Rossi
Bianchi
Età
15
25
85
La query : SELECT Cognome FROM Anagrafica WHERE Età=25 dà come risultato:
Cognome
Rossi
La sintassi vista finora del comando SELECT permette interrogazioni molto semplici, spesso si
cercano dati in maniera molto più complessa, come quando sono presenti relazioni fra tabelle (delle
relazioni tra tabelle parleremo più avanti su queste pagine).
Vediamo
ora
qualche
clausola
WHERE
un
po'
più
complessa:
nella parte che segue il WHERE del comando SELECT può essere inserita una qualsiasi
espressione booleana (cioè una qualsiasi espressione che, risolta, dia come risultato uno dei due
valori booleani (Vero, Falso)) che sia calcolabile, ovviamente nel risultato della query verranno
inserite tutte e sole le righe della tabella che rendono vera l'espressione che segue la clausola
WHERE (Where Condition).
Es: Sia la tabella Dipendenti:
Cognome Nome Età Data_assunzione
Rossi
Mario
40 10/5/1995
Verdi
Giorgina 20 1/3/1999
Bianchi Paolo
50 1/6/1975
Gialli
Loredana 35 24/9/1989
Rossi
Giorgio 46 15/7/1979
SELECT * FROM Dipendenti WHERE True ritorna tutta la tabella,
mentre la query SELECT * FROM Dipendenti WHERE False non ritorna nulla.
SELECT Cognome FROM Dipendenti WHERE Età>35 AND (Cognome='Rossi' OR Nome Like
'Paolo') AND Età<>46
ritorna solamente le seguenti righe:
Cognome Nome Età Data_assunzione
Rossi
Mario 40 10/5/1995
Bianchi Paolo 50 1/6/1975
CONDIZIONI dopo la clausola WHERE
= uguale
< minore
> maggiore
<> diverso
<= minore o uguale
>= maggiore o uguale
LIKE contiene
BETWEEN ... AND compreso tra…. e …..
Nella clausola WHERE se il record deve essere uguale a del testo, allora il testo deve essere incluso
tra gli apici ', in questo modo:
SELECT nome FROM anagrafici WHERE citta = 'Milano'
mentre se il record deve essere uguale ad un numero, gli apici non devono essere utilizzati.
SELECT nome FROM anagrafici WHERE eta = 17
Like
Like permette di ricercare nei records parole, numeri o parti di essi (iniziali, centrali e finali). La
sintassi è leggermente diversa, ma molto semplice:
SELECT nome FROM anagrafici WHERE nome LIKE 'm'
In questo caso vengono dati come risultati tutti i dati, che sono presenti nella colonna nome e che
iniziano per M.
Per cercare invece nomi che finiscono per M si utilizza la seguente query:
SELECT nome FROM anagrafici WHERE nome LIKE '%m'
Infine per cercare nomi che finiscono, iniziano o che contengono la M, si utilizza la seguente query:
SELECT nome FROM anagrafici WHERE nome LIKE '%m%'
AND e OR
AND e OR permettono di indicare due o più condizioni di WHERE. L'operatore AND indica che
tutte le condizioni devono essere vere, mentre OR indica che ne basta una vera.
Sintassi
SELECT records FROM tabella WHERE records CONDIZIONE valore OPERATORE
WHERE records CONDIZIONE valore OPERATORE...
La tabella "anagrafici"
Nome
Lorenzo
Marcello
Michele
Cognome
Pascucci
Tansini
Basso
Eta
17
21
17
Citta
Oriolo Romano
Milano
Udine
Utilizzo di AND
SELECT * FROM anagrafici WHERE eta = 17 AND citta = '%Oriolo%'
Risultato
Lorenzo Pascucci, 17, Oriolo Romano
Utilizzo di OR
SELECT * FROM anagrafici WHERE eta = 21 OR citta = '%Oriolo%'
Risultato
Lorenzo Pascucci, 17, Oriolo Romano
Marcello Tansini, 21, Milano
Utilizzo combinato di AND e OR
SELECT * FROM anagrafici WHERE (nome = 'Lorenzo' OR nome = 'Marcello') AND eta = 17
Risultato
Lorenzo Pascucci, 17, Oriolo Romano
BETWEEN ... AND
Between ... And serve a prelevare dei dati compresi tra due valori.
Sintassi
SELECT records FROM tabella WHERE records BETWEEN valore1 AND valore2
Esempio
La tabella "anagrafici"
Nome
Cognome
Eta
Citta
Lorenzo
Pascucci
17
Oriolo Romano
Marcello
Tansini
21
Milano
Michele
Basso
17
Udine
SELECT nome FROM anagrafici WHERE nome BETWEEN Lorenzo AND Michele
Risultato
Marcello
Dopo la WHERE condition possono essere presenti ancora alcuni comandi:
GROUP BY
HAVING
ORDER BY {Campo1, Campo2, ...} [ASC | DESC]
Il più semplice è ovviamente ORDER BY, che serve per ordinare una tabella rispetto ad uno o più
campi, le parole chiave opzionali in fondo significano il tipo di ordinamento: ASC ( o niente) sta
per ascendente, DESC sta per discendente.
Vediamo subito con un esempio come funziona:
Es: Con la tabella dell'esempio precedente, la query
SELECT * FROM Dipendenti WHERE Età<=40 ORDER BY Cognome DESC
ritorna
Cognome
Verdi
Rossi
Gialli
Nome
Giorgina
Mario
Loredana
Età
20
40
35
Data_assunzione
1/3/1999
10/5/1995
24/9/1989
Se invece non avessimo messo alcunché in fondo o avessimo messo ASC la tabella sarebbe stata
ordinata in ordine crescente rispetto al Cognome.
Si può ordinare anche rispetto a più campi, i campi che vengono dopo il primo sono usati per
l'ordinamento nel caso in cui i valori del primo sono uguali:
SELECT * FROM Dipendenti ORDER BY Cognome, Età
Cognome
Bianchi
Gialli
Rossi
Rossi
Verdi
Nome
Paolo
Loredana
Mario
Giorgio
Giorgina
Età
50
35
40
46
20
Data_assunzione
1/6/1975
24/9/1989
10/5/1995
15/7/1979
1/3/1999
Uno dei più utili comandi all'interno della clausola WHERE è sicuramente il GROUP BY, che
serve per aggregare i dati secondo alcuni criteri; nelle query con questa clausola si possono usare
funzioni che permettono di calcolare medie, somme, massimi, minimi etc; per esempio la funzione
COUNT effettua il conteggio delle righe restituite, mentre la funzione AVG effettua la media dei
valori dell'intervallo.
Nella parte dopo la parola chiave SELECT, che deve contenere i nomi dei campi da estrarre,
possono essere messi solo campi contenuti nella clausola GROUP BY o funzioni di calcolo di
valori su intervalli.
Es: Prendiamo ora invece la tabella Progetti:
Nome_progetto
fax
mail
contabilità
stipendi
SMTP
POP
inventario
Ore_uomo
400
700
3500
7000
400
7000
10500
Ambito
Comunicazioni
Comunicazioni
Gestionale
Gestionale
Comunicazioni
Comunicazioni
Gestionale
La query
SELECT Ambito, Count(*) As TOT, AVG(Ore_uomo) AS MEDIA
FROM Progetti GROUP BY Ambito
Ritorna
Ambito
TOT MEDIA
Comunicazioni 4
2125
Gestionale
3
7000
La funzione AVG effettua la media sui valori contenuti nel campo Ore_uomo, raggruppati secondo
il valore contenuto nel campo Ambito.
La clausola HAVING pone delle condizioni sulle clausole di gruppo, per esempio per considerare
solo i raggruppamenti che hanno più di un certo numero di elementi:
Es: con la stessa tabella dell'esempio precedente, la query
SELECT Count(*) As NUM, Ore_uomo
FROM Progetti
GROUP BY Ore_uomo
HAVING Count(*)>1
NUM Ore_uomo
2
400
2
7000
Che si riferiscono ovviamente alla 1°, 4°, 5° e 6° riga della tabella.
La clausola DISTINCT serve a non ripetere nei risultati lo stesso valore.
SELECT DISTINCT records FROM tabella
Esempio
La tabella "anagrafici"
Nome
Lorenzo
Marcello
Michele
Cognome
Pascucci
Tansini
Basso
Eta
17
21
17
Citta
Oriolo Romano
Milano
Udine
SELECT DISTINCT eta FROM anagrafici
Risultato
17
21
L'età di Michele (17 anni come quella di Lorenzo) non viene data come risultato in quanto già esiste
un risultato dello stesso valore. La stessa cosa vale per le parole...
è differente dal semplice:
SELECT eta FROM anagrafici
in quanto questa istruzione sql avrebbe dato come risultato:
17
21
17