L
Structured Query Language
Abbiamo inserito i dati nel DB,
sappiamo che le informazioni sono nel
sistema informatico, impariamo a
cercarle senza l’aiuto degli informatici.
1
1.1
Breve storia di SQL
In lavorazione
….segue introduzione a SQL
alcune spiegazioni sulle tabelle (Unione – intersezione)
Implementazioni (odbc – jdbc)
Domande e risposte
2
E
2.1
C
T
Obiettivi:
Scrivere una query in linguaggio SQL
Selezionare ed elencare tutte le righe e
le colonne di una tabella
Selezionare ed elencare determinate
colonne di una tabella
Selezionare ed elencare le colonne di più
tabelle
3
2.2
SELECT: regole sintattiche generali
Anche se la parola query può essere tradotta in
interrogazione o domanda, una query SQL non è
necessariamente una domanda, può essere un
comando per svolgere una delle seguenti operazioni:
Creare o cancellare una tabella
Inserire, modificare o cancellare campi
Ricercare informazioni specifiche in più tabelle e
restituire i risultati in un particolare ordine
Modificare i parametri di protezione di un
database
4
2.3
SELECT: regole sintattiche generali
E’ un linguaggio abbastanza flessibile, i
comandi possono essere scritti sia in
maiuscolo che in minuscolo
SELECT NOME, INDIRIZZO, CITTA
FROM PRESIDENTI
WHERE NOME = ‘LINCOLN’;
Select nome, indirizzo, citta
From presidenti
Where nome = ‘LINCOLN’;
I riferimenti ai contenuti di un database devono essere
scritti esattamente come sono stati registrati.
5
2.3
SELECT: regole sintattiche generali
Select nome, indirizzo, citta, from presidenti where nome =
‘LINCOLN’;
Anche questa query è corretta, tuttavia usando con cura la
spaziatura e le lettere minuscole/maiuscole, è
possibile rendere più leggibili le istruzioni:
NOME, INDIRIZZO, CITTA
FROM PRESIDENTI
WHERE NOME = ‘LINCOLN’;
Il ; posto al termine della query serve a segnalare la fine delle istruzioni
6
2.3
SELECT: regole sintattiche generali
Gli elementi importanti di una query sono le parole
chiave ovvero le parole del linguaggio SQL che
sono riservate come parte della sintassi.
Negli esempi precedenti le parole chiavi sono:
SELECT
FROM
WHERE
Consultare il manuale della versione in uso per
conoscere tutte le parole chiave riservate
7
2.4
INFN Laboratori Nazionali di Frascati
SELECT <NOMI DI COLONNE>
FROM <TABELLA>
SQL> SELECT;
SELECT
*
ERROR at line 1;
ORA-00936: missing expression
Parola chiave - istruzione – clausola
La parola chiave si riferisce ai singoli elementi del linguaggio
(SELECT e FROM), una clausola è parte di un’istruzione SQL;
per esempio SELECT colonna1, colonna2, … è una clausola.
Le clausole si combinano per formare un’istruzione completa.
Per esempio è possibile combinare una clausola SELECT e
una clausola FROM per scrivere un’istruzione SQL
SELECT e FROM sono le parole chiave più usate, indispensabili per
stabilire una connessione al computer mirata a leggere i dati
8
2.6
INFN Laboratori Nazionali di Frascati
la prima query
Num
BENEFICIARIO
IMPORTO
1
Computer shop
1.500,00
Dischetti e CD ROM
2
Librerie Riunite
2.453,40
Libri, cancelleria
3
Computer Shop
2.003,20
Telefono cellualare
4
BIOGA srl
5
Supermarket GC
6
Assicurazioni Italy
250,00
Assicurazione casa
7
GAS S.p.A.
251,00
Gas
980,00
1.500,00
NOTE
GAS
Alimentari
SQL> select * from assegni;
Num BENEFICIARIO
1
Computer shop
2
Librerie Riunite
3
Computer Shop
4
BIOGA srl
5
Supermarket GC
6
Assicurazioni Italy
7
GAS S.p.A.
AS/400
IMPORTO
1.500,00
2.453,40
2.003,20
980,00
1.500,00
250,00
251,00
NOTE
Dischetti e CD ROM
Libri, cancelleria
Telefono cellualare
GAS
Alimentari
Assicurazione casa
Gas
L’asterisco (*) di select * indica al database di fornire
TUTTE le colonne associate alla tabella
9
2.6
INFN Laboratori Nazionali di Frascati
Cambiare l’ordine delle colonne
E’ possibile indicare le singole colonne che verranno elencate nello stesso
ordine indicato:
SQL> SELECT beneficiario, note, num, importo from assegni
BENEFICIARIO
Computer shop
Librerie Riunite
Computer Shop
BIOGA srl
Supermarket GC
Assicurazioni Italy
GAS S.p.A.
NOTE
Dischetti e CD ROM
Libri, cancelleria
Telefono cellualare
GAS
Alimentari
Assicurazione casa
Gas
Num
1
2
3
4
5
6
7
IMPORTO
1.500,00
2.453,40
2.003,20
980,00
1.500,00
250,00
251,00
La virgola separa le singole colonne ed è sempre possibile scrivere le
istruzioni su più righe
10
2.6
INFN Laboratori Nazionali di Frascati
Selezionare le colonne
Per selezionare solo alcune colonne basta indicarle, solo quelle dichiarate
verrano elencate nell’ordine indicato:
SQL> SELECT num, importo from assegni
Num
1
2
3
5
6
4
7
IMPORTO
1.500,00
2.453,40
2.003,20
1.500,00
250,00
980,00
251,00
Sono state indicate istruzioni sia in maiuscolo che in minuscolo, come
si può notare il risultato è lo stesso.
AS/400
11
2.6
INFN Laboratori Nazionali di Frascati
Selezionare tabelle differenti
Per selezionare dati da un’altra tabella è sufficiente modificare la clausola
FROM
SQL> SELECT * from depositi
DEPOSITO
1
2
3
CHIHAPAGATO
Zio ricco
Mia azienda
Trasporti S.r.L.
IMPORTO
2000,00
2.453,40
250,00
NOTE
regalo di Natale
Stipendio
Affitto garage
Vengono elencate tutte le colonne della tabella DEPOSITI con le righe
ordinate direttamente dal database
AS/400
12
2.7
INFN Laboratori Nazionali di Frascati
Query senza duplicati
Esaminando il contenuto della tabella assegni
alucni importi sono duplicati:
SQL> SELECT importo from assegni
Per elencare gli importi senza duplicazioni occorre
la clausola DISTINCT
SQL> SELECT DISTINCT importo
from assegni
IMPORTO
1.500,00
2.453,40
2.003,20
980,00
250,00
251,00
IMPORTO
1.500,00
2.453,40
2.003,20
980,00
1.500,00
250,00
251,00
Con la clausola DISTINCT l’output riporta una sola
istanza dei dati duplicati
AS/400
13
2.8
INFN Laboratori Nazionali di Frascati
Riepilogo
Le parole SELECT e FROM consentono a una query di
caricare dei dati.
E’ possibile creare una query generica e includere tutte
le colonne con l’istruzione SELECT *. E’ anche possibile
selezionare solo alcune colonne e anche modificare
l’ordine in cui devono essere presentate.
La parola chiave DISTINCT limita l’output delle query
poiché consente di escludere i valori duplicati di una
colonna.
14
2.9
INFN Laboratori Nazionali di Frascati
Quesiti
Le seguenti query non funzionano. Perché?
a. Select *
b. Select * from assegni
c. Select importo numAssegno beneficiario FROM
assegni;
Quale delle seguenti istruzioni SQL è corretta?
a. select *
from assegni;
b. select * from assegni;
c. select * from assegni /
Le seguenti istruzioni forniscono lo stesso risultato?
SELECT * FROM ASSEGNI
select * from assegni;
AS/400
15
2.10
INFN Laboratori Nazionali di Frascati
Esercizi
1. Utilizzando la tabella ASSEGNI scrivere una query per
selezionare soltanto i numeri e le note degli assegni.
2. Riscrivere la query del precedente esercizio in modo che le
note figurino come prima colonna del risultato della query.
3. Utilizzando la tabella ASSEGNI scrivere una query per ottenere
tutte le note uniche (escludendo quelle duplicate)
AS/400
16
3.1
INFN Laboratori Nazionali di Frascati
Espressioni, condizioni e operatori
Obiettivi
Approfondire le clausole SELECT e FROM, ampliare la
query con qualche nuovo termine e introdurre gli
operatori.
In particolare impareremo a:
Capire cos’è una espressione e come si utilizza
Capire cos’è una condizione e come si utilizza
Familiarizzare con la clausola WHERE
Imparare ad usare gli operatori aritmetici, di
confronto, di caratteri, logici e di insiemi
Conoscere altri utili operatori
17
3.2
INFN Laboratori Nazionali di Frascati
Espressioni
La definizione di espressione è semplice:
un’espressione restituisce un valore
Esistono vari tipi di espressioni in modo da poterle adattare
ai differenti tipi di dati, come le stringhe, i valori
numerici e booleani. Nell’esempio che segue importo è
un’espressione che fornisce il valore della colonna
importo:
SELECT importo from assegni;
AS/400
18
3.2
INFN Laboratori Nazionali di Frascati
Espressioni
Nella seguente istruzione, NOME, INDIRIZZO, TELEFONO E
RUBRICA sono espressioni:
SELECT NOME, INDIRIZZO, TELEFONO, RUBRICA
FROM RUBRICA;
La seguente espressione:
WHERE NOME = ‘ROSSI’
contiene una condizione di una espressione booleana. Questa
condizione potrà essere TRUE (vera) o FALSE (falsa)
rispettivamente se la colonna NOME contiene ROSSI oppure no.
19
3.3
Condizioni
Tutte le volte che si vuole trovare un particolare
elemento o gruppo di elementi in un database,
occorre specificare una o più condizioni.
Le condizioni sono introdotte dalla clausola WHERE.
Nell’esempio precedente la condizione è NOME = ‘ROSSI’
Per trovare tutti gli impiegati che hanno lavorato più di 100
ore la condizione potrebbe essere: NUMERODIORE > 100
20
3.3
INFN Laboratori Nazionali di Frascati
Condizioni
Le condizioni consentono di effettuare query selettive. Nella
forma più comune includono una variabile, una costante e
un operatore di confronto.

Variabile………………………….. NOME

Costante…………………………..’ROSSI’

Operatore di confronto………. >
Per scrivere una query condizionale bisogna conoscere la
clasuola WHERE e gli operatori
21
3.3
INFN Laboratori Nazionali di Frascati
La clausola WHERE
La sintassi della clausola WHERE è la seguente:
WHERE <condizione di ricerca>
La clausola WHERE rende selettive le query, senza questa clausola
la query visualizzerebbe tutti i record della tabella:
SQL> SELECT * FROM BICICLETTE;
NOME
TELAIO
MATERIALE
Km percorsi
tipo
TREK 2300
57
FIBRA DI CARBONIO
3500
CORSA
GIANT
56
ACCIAIO
2000
TANDEM
BIANCHI
53
ACCIAIO
1500
PASSEGGIO
COLNAGO
54
ACCIAIO
500
VIAGGIO
COPPI
53
ACCIAIO
100
MOUNTAIN
DE ROSA
57
ALLUMINIO
300
CORSA
22
3.3
INFN Laboratori Nazionali di Frascati
La clausola WHERE
Per selezionare una particolare bicicletta si può usare la
seguente query:
SELECT * FROM BICICLETTE WHERE NOME = ‘GIANT’;
che fornisce un solo record:
NOME
GIANT
TELAIO
56
MATERIALE
ACCIAIO
Km percorsi
2000
tipo
TANDEM
Questo semplice esempio mostra come applicare una
condizione sui dati da caricare
23
3.4
INFN Laboratori Nazionali di Frascati
Operatori
Gli operatori sono gli elementi utilizzati all’interno
delle espressioni per specificare le condizioni
necessarie a caricare i dati.
Possono essere divisi in sei gruppi:






aritmetici
di confronto
di caratteri
logici
di insieme
vari
E’ un potente gruppo di strumenti a base della conoscenza
del linguaggio SQL
24
3.4
INFN Laboratori Nazionali di Frascati
Operatori aritmetici
1. + (somma)
2. - (sottrazione)
3. / (divisione)
4.
5.
* (moltiplicazione)
% (modulo o resto)
I primi quattro operatori si spiegano da soli.
L’operatore modulo restituisce il resto di una divisione. Ad
esempio:
5%2=1
6%2=0
Non funziona con i tipi di dati che hanno cifre decimali
25
3.4
INFN Laboratori Nazionali di Frascati
Operatori aritmetici
Se vengono inseriti più operatori aritmetici in una
espressione senza parentesi, essi vengono valutati
nell’ordine: moltiplicazione, divisione, modulo, somma
e sottrazione. Ad esempio:
2*6+9/3
vale
12 + 3 = 15
vale
2 * 15 / 3 = 10
mentre l’espressione
2 * (6 + 9) / 3
Attenzione alla posizione delle parentesi!
26
3.4
L’operatore somma (+)
INFN Laboratori Nazionali di Frascati
Può essere usato in vari modi. La seguente espressione
visualizza il contenuto della tabella PREZZO:
SQL> SELECT * FROM PREZZO
SQL> SELECT ELEMENTO, PREZZOINGROSSO,
PREZZOINGROSSO + 150 FROM PREZZO
ELEMENTO
PREZZOINGROSSO
ELEMENTO
PREZZOINGROSSO
Pomodori
3,40
Pomodori
3,40
4,90
Patate
5,10
Patate
5,10
6,60
Banane
6,70
Banane
6,70
8,20
Rape
4,50
Rape
4,50
6,00
Arance
8,90
Arance
8,90
10,40
Mele
2,30
Mele
2,30
4,80
PREZZOINGROSSO + 150
La terza colonna (PREZZOINGROSSO + 150) non si trova nella tabella
originale (in entrambi i casi sono state selezionate con il carattere * tutte
le colonne).
SQL consente di creare colonne virtuali o derivate combinando o modificando le
colonne esistenti.
27
3.4
INFN Laboratori Nazionali di Frascati
L’operatore somma (+)
E’ possibile assegnare una intestazione più
comprensibile alla nuova colonna:
SQL> SELECT ELEMENTO, PREZZOINGROSSO,
(PREZZOINGROSSO + 1.50) PREZZODETTAGLIO FROM PREZZO
ELEMENTO PREZZOINGROSSO
PREZZODETTAGLIO
Pomodori
3,40
4,90
Patate
5,10
6,60
Banane
6,70
8,20
Rape
4,50
6,00
Arance
8,90
10,40
Mele
2,30
3,80
28
3.4
INFN Laboratori Nazionali di Frascati
L’operatore somma (+)
E’ possibile assegnare una intestazione più
comprensibile anche a colonne esistenti:
SQL> SELECT ELEMENTO PRODOTTO, PREZZOINGROSSO,
(PREZZOINGROSSO + 1.50) PREZZODETTAGLIO FROM PREZZO
PRODOTTO
PREZZOINGROSSO
PREZZODETTAGLIO
Pomodori
3,40
4,90
Patate
5,10
6,60
Banane
6,70
8,20
Rape
4,50
6,00
Arance
8,90
10,40
Mele
2,30
3,80
La colonna ELEMENTO è stata ridenominata PRODOTTO.
E’ comunque consigliabile consultare la documentazione della propria
implementazione SQL per conoscere la sintassi esatta.
29
3.4
INFN Laboratori Nazionali di Frascati
L’operatore sottrazione (-)
L’operatore meno svolge due funzioni, la prima è quella di
cambiare segno ad un numero:
SQL> SELECT * FROM MINMAX
REGIONE
TEMPMAX
TEMPMIN
Piemonte
-4
10
Toscana
4
13
Sicilia
10
19
Lombardia
-2
9
Friuli
-3
8
SQL> SELECT REGIONE, -TEMPMAX, -TEMPMIN
FROM MINMAX
REGIONE
TEMPMAX
TEMPMIN
Piemonte
4
-10
Toscana
-4
-13
-10
-19
Lombardia
2
-9
Friuli
3
-8
Sicilia
30
3.4
L’operatore sottrazione (-)
INFN Laboratori Nazionali di Frascati
La seconda (e ovvia) funzione dell’operatore meno è quella di
sottrarre i valore di una colonna da quelli di un’altra colonna.
Esempio:
SQL> SELECT REGIONE,
TEMPMAX MINIME,
TEMPMIN MASSIME,
(TEMPMIN - TEMPMAX) DIFFERENZA
FROM MINMAX;
REGIONE
MINIME
MASSIME
DIFFERENZE
Piemonte
-4
10
14
Toscana
4
13
9
Sicilia
10
19
9
Lombardia
-2
9
11
Friuli
-3
8
11
Oltre che aver creato la nuova colonna questa query ha corretto (solo
sullo schermo) i nomi di quelle errate.
31
3.4
INFN Laboratori Nazionali di Frascati
L’operatore sottrazione (-)
Se venisse utilizzato accidentalmente l’operatore meno su un
campo caratteri si otterrà un messaggio simile a questo:
SQL> SELECT – REGIONE FROM MINMAX
ERROR:
ORA-01722: invalid number
no row selected
Il testo del messaggio varia da un’implementazione all’altra, ma il risultato è
lo stesso
32
3.4
L’operatore divisione (/)
INFN Laboratori Nazionali di Frascati
L’operatore divisione ha un solo significato, per vedere gli effetti
di una vendita a metà prezzo basta digitare la seguente
istruzione:
SQL> SELECT ELEMENTO PRODOTTO, PREZZOINGROSSO,
(PREZZOINGROSSO/2) PREZZOVENDITA FROM PREZZO
ELEMENTO PREZZOINGROSSO
PREZZOVENDITA
Pomodori
3,40
1,70
Patate
5,10
2,55
Banane
6,70
3,35
Rape
4,50
2,25
Arance
8,90
4,45
Mele
2,30
1,15
L’uso dell’operatore divisione in questa istruzione SELECT è semplice, anche se
vendere a metà prezzo non è proprio convienente.
33
3.4
INFN Laboratori Nazionali di Frascati
L’operatore moltiplicazione (*)
Anche l’’operatore moltiplicazione è semplice da usare, ad
esempio questa query visualizza l’effetto di uno sconto del 10%
sui prezzi di tutti i prodotti:
SQL> SELECT ELEMENTO PRODOTTO, PREZZOINGROSSO,
(PREZZOINGROSSO*0.9) NUOVOPREZZO FROM PREZZO;
ELEMENTO
PREZZOINGROSSO
NUOVOPREZZO
Pomodori
3.40
3.06
Patate
5.10
4.59
Banane
6.70
6.03
Rape
4.50
4.05
Arance
8.90
8.01
Mele
2.30
2.07
Questi operatori permettono di svolgere con grande efficienza calcoli
aritmetici nell’istruzione SELECT
34
3.4
L’operatore modulo (%)
L’operatore modulo restituisce il resto intero di una operazione di
divisione. Esempio:
SQL> SELECT * FROM
RESTI
NUMERATORE
DENOMINATORE
10
5
8
3
23
9
1024
16
E’ possibile creare una nuova colonna, RESTO, dove registrare il resto
della divisione tra NUMERATORE e DENOMINATORE
SQL> SELECT NUMERATORE, DENOMINATORE,
NUMERATORE%DENOMINATORE RESTO
FROM RESTI
NUMERATORE
DENOMINATORE
RESTO
10
5
0
8
3
2
23
9
5
1024
16
0
35
3.4
INFN Laboratori Nazionali di Frascati
Operatori di confronto
Questi operatori confrontano le espressioni e restituiscono uno di questi
tre valori: TRUE, FALSE, Unkown. I primi due sono semplici da
spiegare, TRUE significa vero e FALSE significa falso, il terzo,
Unknow, identifica l’assenza di dati in una colonna, cioè NULL.
Molte implementazioni SQL cambiano Unknown in FALSE e forniscono un
operatore speciale, IS NULL, per verificare la condizione NULL (assenza
di dati).
SQL> SELECT * FROM PREZZO WHERE PREZZOINGROSSO = NULL;
No row selected
SQL> SELECT * FROM PREZZO WHERE PREZZOINGROSSO IS NULL;
ELEMENTO PREZZOINGROSSO
Limoni
Nel database la colonna prezzoingrosso della riga Limoni non contiene
dati (non è zero)
36
3.4
L’operatore (=)
INFN Laboratori Nazionali di Frascati
Nella clausola WHERE il segno uguale è l’operatore di confronto
più utilizzato, molto comodo per selezionare un valore tra tanti.
SQL> SELECT * FROM AMICI;
COGNOME
NOME
CITTA
TELEFONO
ROSSI
ALE
MILANO
02 3425678
BIANCHI
SABY
TORINO
011 6707221
BROWN
JO
PISA
NERI
ALE
BOLOGNA
050 880245
051 6711
SQL> SELECT * FROM AMICI WHERE NOME = ‘ALE’;
COGNOME
NOME
CITTA
TELEFONO
ROSSI
ALE
MILANO
02 3425678
NERI
ALE
BOLOGNA
051 6711
SQL> SELECT * FROM AMICI WHERE NOME = ‘Ale’;
no row selected.
37
3.4
INFN Laboratori Nazionali di Frascati
L’ operatore maggiore (>) e maggiore uguale (>=)
questi operatori operano nel seguente modo modo:
SQL> SELECT * FROM PREZZO;
ELEMENTO
PREZZOINGROSSO
Pomodori
3.40
Patate
5.10
Banane
6.70
Rape
4.50
Arance
8.90
Mele
2.30
SQL> SELECT * FROM PREZZO
WHERE PREZZOINGROSSO > 4.50;
ELEMENTO
PREZZOINGROSSO
Patate
5.10
Banane
6.70
Arance
8.90
SQL> SELECT * FROM PREZZO
WHERE PREZZOINGROSSO >= 4.50;
ELEMENTO
PREZZOINGROSSO
Patate
5.10
Banane
6.70
Rape
4.50
Arance
8.90
Non si usano apici per racchiudere il numero 4.50
38
3.4
INFN Laboratori Nazionali di Frascati
L’operatore maggiore (<) e maggiore uguale (<=)
questi operatori operano in senso inverso al precedente:
SQL> SELECT * FROM AMICI;
COGNOME
NOME
CITTA
TELEFONO
ROSSI
ALE
MILANO
02 3425678
BIANCHI
SABY
TORINO
011 6707221
BROWN
JO
PISA
NERI
ALE
BOLOGNA
050 880245
051 6711
SQL> SELECT * FROM AMICI
WHERE CITTA < ‘MILANO’ ;
COGNOME
NOME
CITTA
TELEFONO
BROWN
JO
PISA
050 880245
NERI
ALE
BOLOGNA
051 6711
Ovviamente è possibile applicarli anche a valori alfabetici,
per la sequenza corretta consultare la propria implementazione SQL
39
3.4
INFN Laboratori Nazionali di Frascati
L’operatore di diseguaglianza (<> o !=)
Consente di trovare dati escludendone altri,
cioè il simbolo (<>) oppure (!=) si legge “diverso da”.
Per trovare gli amici tranne ALE (cioè con il nome diverso da ALE):
SQL> SELECT * FROM AMICI
WHERE NOME <> ‘ALE’;
COGNOME
NOME
CITTA
BIANCHI
SABY
TORINO
BROWN
JO
PISA
NERI
ALE
BOLOGNA
TELEFONO
011 6707221
050 880245
051 6711
In molte implementazione SQL è indifferente usare la forma (<>) anzichè (!=)
40
3.4
Gli operatori di carattere
INFN Laboratori Nazionali di Frascati
Consentono di manipolare il modo in cui debbono essere rappresentate le
stringhe durante la preparazione delle condizioni che selezionano i dati.
L’operatore LIKE
consente di estrarre dati che somigliano ad un certo schema
NOME
POSIZIONE
NUMEROPARTE
FEGATO
DESTRA-ADDOME
1
CUORE
PETTO
2
FARINGE
GOLA
3
VERTEBRE
CENTRO-DORSO
4
INCUDINE
ORECCHIO
5
RENE
DORSO
6
Come fare a trovare tutte le parti che si trovano nella zona dorsale del corpo?
Osservando la tabella è possibile individuarne due, ma hanno nomi differenti.
41
3.4
INFN Laboratori Nazionali di Frascati
L’operatore LIKE
NOME
POSIZIONE
NUMEROPARTE
FEGATO
DESTRA-ADDOME
1
CUORE
PETTO
2
FARINGE
GOLA
3
VERTEBRE
CENTRO-DORSO
4
INCUDINE
ORECCHIO
5
RENE
DORSO
6
SQL> SELECT * FROM PARTI WHERE POSIZIONE LIKE ‘%DORSO%’;
NOME
POSIZIONE
NUMEROPARTE
VERTEBRE
CENTRO-DORSO
4
RENE
DORSO
6
SQL> SELECT * FROM PARTI WHERE POSIZIONE LIKE ‘DORSO%’;
NOME
POSIZIONE
RENE
DORSO
NUMEROPARTE
6
SQL> SELECT * FROM PARTI WHERE POSIZIONE LIKE ‘%DORSO’;
NOME
POSIZIONE
VERTEBRE
CENTRO-DORSO
NUMEROPARTE
4
42
3.4
INFN Laboratori Nazionali di Frascati
L’operatore LIKE
NOME
POSIZIONE
NUMEROPARTE
FEGATO
DESTRA-ADDOME
1
CUORE
PETTO
2
FARINGE
GOLA
3
VERTEBRE
CENTRO-DORSO
4
INCUDINE
ORECCHIO
5
RENE
DORSO
6
SQL> SELECT * FROM PARTI WHERE NOME LIKE ‘F%’;
NOME
POSIZIONE
NUMEROPARTE
FEGATO
DESTRA-ADDOME
1
FARINGE
GOLA
3
SQL> SELECT * FROM PARTI WHERE POSIZIONE LIKE ‘f%’;
no rows selected.
L’operatore like è sempre sensibile ai caratteri minuscoli/maiuscoli
43
3.4
INFN Laboratori Nazionali di Frascati
Il carattere di sottolineatura (_)
Il carattere di sottolineatura è un carattere jolly singolo.
COGNOME
NOME
CITTA
PROVINCIA
TELEFONO
ROSSI
ALE
MILANO
MI
02 3425678
BIANCHI
SABY
TORINO
TO
011 6707221
BROWN
JO
PISA
PI
050 880245
NERI
ALE
BOLOGNA
BO
051 6711
SQL> SELECT * FROM AMICI WHERE PROVINCIA LIKE ‘_O’;
COGNOME
NOME
CITTA
PROVINCIA
TELEFONO
BIANCHI
SABY
TORINO
TO
011 6707221
NERI
ALE
BOLOGNA
BO
051 6711
E’ possibile utilizzare più di un carattere di sottolineatura e può essere
combinato con l’operatore LIKE.
44
3.4
L’operatore di concatenazione (||)
INFN Laboratori Nazionali di Frascati
Il simbolo || serve a concatenare due stringhe:
COGNOME
NOME
CITTA
PROVINCIA
TELEFONO
ROSSI
ALE
MILANO
MI
02 3425678
BIANCHI
SABY
TORINO
TO
011 6707221
BROWN
JO
PISA
PI
050 880245
NERI
ALE
BOLOGNA
BO
051 6711
SQL> SELECT NOME || COGNOME NOMECOMPLETO FROM AMICI;
NOMECOMPLETO
ROSSI
ALE
BIANCHI
SABY
BROWN
JO
NERI
ALE
Se si utilizzasse il segno + per concatenare due stringhe, l’interprete SQL
fornirebbe un messaggio d’errore:
SQL> SELECT NOME + COGNOME NOMECOMPLETO FROM AMICI;
ERROR:
ORA-01722: invalid member
45
3.4
INFN Laboratori Nazionali di Frascati
Gli operatori logici
Negli esempi precedenti è stato effettuato sempre un controllo alla
volta. Questo metodo va bene per i casi semplici, ma come fareste a
trovare tutti quei dipendenti I cui nomi iniziano con la lettera P e che
hanno meno di tre giorni di ferie?
Gli operatori logici separano due o più condizioni nella clausola
WHERE di un’istruzione SQL.
Essi sono:
 AND
 OR
 NOT
46
3.4
INFN Laboratori Nazionali di Frascati
Esempio operatore AND
Si supponga che un’azienda conceda 12 giorni di ferie per ogni anno
lavorativo. In base a quanto detto sarà scritta una query per trovare tutti gli
impiegati i cui nomi iniziano con la lettera B ed hanno più di 50 giorni di ferie
da godere:
COGNOME
SQL>
NUMDIP
ANNI
FERIEGODUTE
ABITA
101
2
4
BACCHI
104
5
23
BLESSI
107
8
45
BOLIVAR
233
4
80
BOLDI
210
15
100
COSTALES
211
10
78
SELECT COGNOME,
ANNI * 12 – FERIEGODUTE [AS] FERIERESTANTI
FROM TABELLAFERIE
WHERE COGNOME LIKE ‘’B%’
AND
ANNI * 12 – FERIEGODUTE > 50;
COGNOME
FERIERESTANTI
BLESSI
51
BOLDI
80
47
3.4
INFN Laboratori Nazionali di Frascati
L’operatore AND
L’operatore logico AND indica che entrambe le espressioni che si trovano ai
suoi lati devono essere soddisfatte per restituire il valore TRUE (vero). Se una
solo delle espressioni non è soddisfatta l’operatore AND restituisce FALSE.
Ad esempio, per sapere quali impiegati hanno lavorato per l’azienda per 5
anni o meno ed hanno utilizzato più di 20 giorni di ferie, si può scrivere:
COGNOME
SQL>
SELECT *
FROM FERIE
WHERE ANNI <= 5
AND
FERIEGODUTE > 20;
COGNOME
NUMDIP
ANNI
FERIEGODUTE
ABITA
101
2
4
BACCHI
104
5
23
BLESSI
107
8
45
BOLIVAR
233
4
80
BOLDI
210
15
100
COSTALES
211
10
78
NUMDIP
ANNI
FERIEGODUTE
BACCHI
104
5
23
BOLIVAR
233
4
80
48
3.4
INFN Laboratori Nazionali di Frascati
L’operatore OR
L’operatore logico OR puo’ essere utilizzato per combinare una serie di
condizioni. Se una di queste è soddisfatta viene restituito TRUE
COGNOME
SQL>
SELECT *
FROM FERIE
WHERE COGNOME LIKE ‘BO%’
OR
COGNOME LIKE ‘CO%’;
COGNOME
NUMDIP
ANNI
FERIEGODUTE
ABITA
101
2
4
BACCHI
104
5
23
BLESSI
107
8
45
BOLIVAR
233
4
80
BOLDI
210
15
100
COSTALES
211
10
78
NUMDIP
ANNI
FERIEGODUTE
BOLDI
210
15
100
BOLIVAR
233
4
80
COSTALES
211
10
78
L’operatore OR richiede che una soltanto delle condizioni sia vera affinchè I
dati possano essere restitutiti
49
3.4
INFN Laboratori Nazionali di Frascati
L’operatore NOT
L’operatore logico NOT ha il compito di invertire il significato di una
condizione
COGNOME
SQL>
NUMDIP
ANNI
FERIEGODUTE
ABITA
101
2
4
BACCHI
104
5
23
BLESSI
107
8
45
BOLIVAR
233
4
80
BOLDI
210
15
100
211
10
78
COSTALES
SELECT *
FROM FERIE
WHERE COGNOME NOT LIKE ‘B%’;
COGNOME
NUMDIP
ANNI
FERIEGODUTE
BOLDI
210
15
100
BOLIVAR
233
4
80
COSTALES
211
10
78
L’operatore OR richiede che una soltanto delle condizioni sia vera affinchè I
dati possano essere restitutiti
50
3.4
INFN Laboratori Nazionali di Frascati
Gli operatori di insieme: UNION
L’operatore UNION restituisce il risultato di due query escludendo le righe
duplicate.
Esempio: quante persone diverse giocano in entrambe le squadre?
COGNOME
COGNOME
ABITA
ABITA
BRAVO
CARLINI
DECCA
SQL>
SELECT COGNOME FROM CALCETTO
UNION
SELECT COGNOME FROM CALCIO;
ESTERLE
FUNDARI
GIANI
calcetto
BACCO
CARLINI
DINI
ESTERLE
COGNOME
FALCONI
ABITA
GIANI
BACCO
calcio
BRAVO
CARLINI
DECCA
DINI
ESTERLE
Sono stati esclusi i doppioni
FALCONI
FUNDARI
GIANI
A C B
A+B-C
AS/400
51
3.4
Gli operatori di insieme: UNION ALL
INFN Laboratori Nazionali di Frascati
L’operatore UNION ALL restituisce il risultato di due query incluse
le righe duplicate.
Esempio: quante persone giocano al calcetto e quante al calcio?
SQL>
SELECT COGNOME FROM CALCETTO
UNION ALL
SELECT COGNOME FROM CALCIO;
COGNOME
ABITA
BRAVO
CARLINI
DECCA
ESTERLE
FUNDARI
GIANI
calcetto
COGNOME
A+B
ABITA
BRAVO
CRLINI
DECCA
ESTERLE
FUNDARI
GIANI
ABITA
BACCO
CARLINI
DINI
ESTERLE
Sono incluse tutte le righe
A C B
COGNOME
ABITA
BACCO
CARLINI
DINI
ESTERLE
FALCONI
GIANI
calcio
FALCONI
GIANI
AS/400
52
3.4
Gli operatori di insieme: INTERSECT
INFN Laboratori Nazionali di Frascati
L’operatore INTERSECT restituisce soltanto le righe che vengono
trovate in entrambe le query
Esempio: quali persone giocano in entrambe le squadre?
SQL>
SELECT COGNOME FROM CALCETTO
INTERSECT
SELECT COGNOME FROM CALCIO;
select * from corso.calcio
where cognome in (select cognome from corso.calcetto)
calcetto
A C B
calcio
COGNOME
COGNOME
ABITA
ABITA
BRAVO
BACCO
CARLINI
DECCA
ESTERLE
FUNDARI
GIANI
COGNOME
ABITA
CRLINI
ESTERLE
GIANI
CARLINI
DINI
ESTERLE
FALCONI
GIANI
C
Sono inclusi solo le righe comuni
NON AS/400
53
3.4
INFN Laboratori Nazionali di Frascati
Gli operatori di insieme: MINUS (differenza)
L’operatore MINUS restituisce le righe della prima query che non
sono presenti nella seconda
Esempio: quali persone giocano solo al calcetto?
SQL>
SELECT COGNOME FROM CALCETTO
MINUS
SELECT COGNOME FROM CALCIO;
COGNOME
COGNOME
ABITA
COGNOME
ABITA
BRAVO
BACCCO
BACCO
CARLINI
DINI
CARLINI
DECCA
FALCONI
DINI
ESTERLE
FUNDARI
ESTERLE
A C B
GIANI
calcetto
FALCONI
GIANI
A-C
calcio
Seleziona quelli che giocano solo al calcetto
NON AS/400
54
3.4
INFN Laboratori Nazionali di Frascati
Gli operatori di insieme: IN e BETWEEN
Forniscono la scorciatoia per operazioni che possono essere svolte
in altri modi, ad esempio:
Quali amici vivono in provincia di Como, Pavia e Bergamo?
SQL>
SELECT * FROM AMICI
WHERE PROVINCIA = ‘CO’
OR PROVINCIA = ‘PV’
OR PROVINCIA = ‘BG’;
In alternativa si può usare la seguente query:
SQL>
SELECT * FROM AMICI
WHERE PROVINCIA IN (‘CO’, ‘PV’, ‘‘BG’);
L’operatore IN può essere utilizzato anche per i numeri:
SQL>
SELECT * FROM DIPENDENTI
WHERE ETASERVIZIO IN (15, 25, 40);
Verrano selezionati I dipendenti che hanno ETASERVIZIO uguale
ad uno dei tre valori espressi
55
3.4
INFN Laboratori Nazionali di Frascati
L’operatore BETWEEN
Consente di definire come condizione un intervallo di valori.
Ad esempio per estrarre dalla tabella PREZZO quei prodotti i cui prezzi siano
compresi in un determinato intervallo, si può utilizzare la seguente query:
SQL>
SELECT * FROM PREZZO
WHERE PREZZOINGROSSO > 2.50
AND
ELEMENTO
PREZZOINGROSSO < 7.50;
PREZZOINGROSSO
Pomodori
3.40
Patate
5.10
Banane
6.70
Rape
4.50
In alternativa si può utilizzare l’operatore BETWEEN:
SQL>
SELECT * FROM PREZZO
WHERE PREZZOINGROSSO BETWEEN 2.50 AND 7.50;
ELEMENTO
PREZZOINGROSSO
Pomodori
3.40
Patate
5.10
Banane
6.70
Rape
4.50
Se nella tabella prezzo ci fosse stato un valore di PREZZOINGROSSO pari a 2.50. Il
corrispondente record sarebbe stato estratto. I parametri dell’operatore BETWEEN
sono inclusivi
56
3.5
INFN Laboratori Nazionali di Frascati
AMICI
Quesiti
Utilizzare la tabella AMICI
per rispondere ai quesiti successivi
1.
2.
3.
4.
5.
COGNOME
NOME
TELEFONO
PROVINCIA
BUNDI
ALE
555-1111
BG
MEZA
ALE
555-222
MI
MERRILI
SABY
555-6666
CO
MAZZA
JO
555-6767
PV
BANFI
BARBY
555-3223
BG
BORDON
SIR
555-3116
CT
PERSIANI
ALBY
555-2345
CA
Scrivere una query per selezionare tutti i cognomi che iniziano con la
lettera M;
Scrivere una query per selezionare gli amici che vicono in provincia di
Bergamo e il cui nome è Ale;
Date due tabelle (PARTE1 e PARTE2) che contengono una colonna
chiamata NUMPARTE, come fareste a trovare quei numeri che
appartengono ad entrambe le tabelle? Scrivere la query;
Quale scorciatoia potrebbe essere utilizzata in alternativa a
WHERE a >=10 AND a<=30?
Qual è il risultato di questa query?
SELECT NOME
FROM AMICI
WHERE NOME = ‘ALE’
AND COGNOME = ‘BANFI’;
57
3.6
INFN Laboratori Nazionali di Frascati
Esercizi
COGNOME
NOME
TELEFONO
PROVINCIA
BUNDI
ALE
555-1111
BG
MEZA
ALE
555-222
MI
MERRILI
SABY
555-6666
CO
MAZZA
JO
555-6767
PV
BANFI
BARBY
555-3223
BG
BORDON
SIR
555-3116
CT
PERSIANI
ALBY
555-2345
CA
1. Utilizzando la tabella AMICI, scrivere una query che fornisce il
seguente risultato:
NOME
PROVINCIA
ALE
BG
2. Utilizzando la tabella AMICI, scrivere una query che fornisce il
seguente risultato:
NOMECOMPLETO
TELEFONO
MERRILI, SABY
555-6666
MAZZA, JO
555-6767
BANFI, BARBY
555-3223
58
4.1
Funzioni
INFN Laboratori Nazionali di Frascati
Obiettivi
Descrivere le funzioni del linguaggio SQL.
Le funzioni permettono di svolgere varie operazioni, come la somma dei
contenuti di una colonna o la trasformazione in maiuscolo di tutti I
caratteri di una stringa.
Al termine avremo imparato a conoscere ed usare quelle principali
Aggregate
Temporali
Aritmetiche
Di caratteri
Di conversione
varie
59
4.1
INFN Laboratori Nazionali di Frascati
Funzioni aggregate: COUNT
Restituisce il numero di righe che soddisfano la condizione
specificata nella clausola WHERE
SQL> SELECT COUNT(*)
FROM INFN03.INVGEN
WHERE TIPOBENE = 'L';
COUNT(*)
521
Per rendere più leggibile codice e output si può usare l’alias:
SQL> SELECT COUNT(*) LIBRI
FROM INFN03.INVGEN
WHERE TIPOBENE = 'L';
LIBRI
521
Se fosse indicato un campo al posto dell’asterisco il risultato non
cambierebbe:
SQL> SELECT COUNT(NUMINV) LIBRI
FROM INFN03.INVGEN
WHERE TIPOBENE = 'L';
LIBRI
521
AS/400
60
4.1
INFN Laboratori Nazionali di Frascati
Funzioni aggregate: COUNT
E se non venisse specificata la clausola WHERE?
SQL> SELECT COUNT(*)
FROM INFN03.INVGEN;
COUNT(*)
2584
Senza la clausola WHERE la query fornisce il numero di record
della tabella.
Nell’esempio ritorna il numero complessivo di tutti i record
presenti nell’inventario (Libri-Varie-Immobili)
AS/400
61
4.1
INFN Laboratori Nazionali di Frascati
SUM
La funzione SUM somma tutti i valori di una colonna.
SQL> SELECT SUM(IMPVAR) VARIAZIONI
FROM INFN03.CMOV3;
VARIAZIONI
-27723897
SQL> SELECT SUM(IMPVAR) * 0.01 VARIAZIONI
FROM INFN03.CMOV3;
VARIAZIONI
-277238.97
SQL> SELECT SUM(DESVAR) * 0.01 VARIAZIONI
FROM INFN03.CMOV3;
Error: [SQL0402] SUM use not valid.
Calcolare la media dell’importo delle variazioni
SQL> SELECT SUM(IMPVAR) * 0.01/ count(*) MEDIAVARIAZIONI
FROM INFN03.CMOV3;
MEDIAVARIAZIONI
-208.45
AS/400
62
4.1
MAX
INFN Laboratori Nazionali di Frascati
La funzione MAX serve a trovare il valore massimo di una
colonna.
SQL> SELECT MAX(IMPVAR) VARIAZMAX
FROM INFN03.CMOV3;
SQL> SELECT MAX(IMPVAR) * 0.01 VARIAZMAX
FROM INFN03.CMOV3;
VARIAZMAX
470000
VARIAZMAX
4700.00
Quale centro di costo ha la variazione più alta?
SQL> SELECT PREVEN
FROM INFN03.CMOV3
WHERE IMPVAR = MAX(IMPVAR)
Error at line 3:
ORA-00934 group function is not alllowed here
Putroppo questa istruzione non funziona. La funzione di gruppo
non può essere usata con la clausola WHERE, la soluzione è
quella di utilizzare le subquery.
La funzione MAX opera anche con le stringhe, ritorna la stringa
massima, cioè più vicina alla lettera Z.
AS/400
63
4.1
INFN Laboratori Nazionali di Frascati
MIN
Opera in modo analogo alla funzione MAX, ovviamente
restituisce il valore minimo della colonna
SQL> SELECT MIN(IMPVAR) VARIAZMIN
FROM INFN03.CMOV3;
SQL> SELECT MIN(IMPVAR) * 0.01 VARIAZMIN
FROM INFN03.CMOV3;
VARIAZMIN
-5000000
VARIAZMIN
-50000.00
E’ possibile combinare le funzioni MIN e MAX per stabilire un
intervallo di valori (può essere utile con le funzioni statistiche):
SQL> SELECT MIN(IMPVAR) MINIMO, MAX(IMPVAR) MASSSIMO
FROM INFN03.CMOV3;
VARIAZMIN
4700.00
VARIAZMAX
-50000.00
AS/400
64
4.1
Funzioni temporali
INFN Laboratori Nazionali di Frascati
La società è governata da date e orari, la maggior parte delle implementazioni SQL
dispone di funzioni specifiche.
Con queste funzioni è possibile aggiungere mesi ad una data specifica, individuare
l’ultimo giorno del mese indicato nella data, conoscere la data del sistema,
sapere quanti mesi separano due date ed altro.
Ad esempio per conoscere quali compiti hanno avuto inizio prima del 19 maggio
1995:
SQL> SELECT *
FROM PROGETTO
WHERE MONTHS_BETWEEN(’19 MAY 95’, DATASTART) > 0;
COMPITO
DATASTART
DATAFINE
AVVIO PROGETTO
01-APR-95
01-APR-95
DEF. SPECIFICHE
02-APR-95
01-MAG-95
CHECK TECNICO
15-MAY-95
30-MAY-95
MONTS_BETWEEN(’19 MAY 95’, DATASTART)
Questa funzione ritorna il numero di mesi che sono compresi tra le due date
65
4.1
INFN Laboratori Nazionali di Frascati
Funzioni di carattere
Sono funzioni che consentono di manipolare i caratteri e le stringhe. Come le
funzioni aritmetiche e trigonometriche sono utilizzate essenzialmente
dai programmatori, si consiglia di consultare I manuali specifici qualora
se ne avvertisse la necessità.
Quella che risulta particolarmente utile è la
funzione SUBSTR
Questa funzione consente di estrarre una serie di caratteri (sottostringa ) da
una stringa specificata.
SUBSTR richiede tre argomenti:
1. La stringa da esaminare,
2. La posizione del primo carattere da estrarre,
Lunghezza
3. Il numero di caratteri da estrarre
sottostringa
SQL> SELECT SUBSTR(CAMPO, 2, 3)……..
Nome colonna
Posizione
iniziale
66
4.1
INFN Laboratori Nazionali di Frascati
SUBSTR
Nelle attuali applicazioni contabili si chiede di inserire il capitolo ma in realtà
con esso si chiede di inserire anche il titolo e la categoria.
Ad esempio per indicare quello relativo alla cancelleria usiamo scrivere
104020, in realtà noi intendiamo 1 04 020, cioè specifichiamo il titolo I
(spese correnti), la categoria IV (consumo) e infine 020 (cancelleria
ecc.).
In questa caso torna utilissimo disporre della funzione SUBSTR per avere
informazioni relative alle singoli sottostringhe che compongono il
capitolo 104020.
SQL> SELECT SUBSTR(digits(CAPIT), 1, 1)TITOLO,
SUBSTR(digits(CAPIT), 2, 2)CATEGORIA
altre colonne
FROM INFN03.CMOV3
WHERE SUBSTR(digits(CAPIT), 2, 2) = '04'
Verranno selezionate le righe della tabella variazioni relative alla
sola categoria IV (consumo)
Il troncamento di colonne molto larghe migliora la leggibilità del risultato di
una query
AS/400
67
4.1
INFN Laboratori Nazionali di Frascati
SUBSTR
Esempio:
Calcolare l’ammontare complessivo delle variazioni relative ai capitoli della
categoria IV (consumo) residui e competenza
SQL> SELECT SUM(IMPVAR* 0.01) AS VARIAZIONICONSUMO
FROM INFN03.CMOV3
WHERE SUBSTR(DIGITS(CAPIT),2,2) = '04'
VARIAZIONICONSUMO
-112587.07
AS/400
68
4.1
INFN Laboratori Nazionali di Frascati
CONCAT
Questa funzione consente di unire due stringhe, ad esempio:
SQL> SELECT CONCAT(nome, cognome) "Nome e Cognome"
FROM AMICI;
Nome e Cognome
ALE
BUNDI
ALE
MEZA
SABY
MERRILLI
L’esempio presuppone che nella tabellaX la colonna relativa al nome sia
distinta da quella del cognome
Esistono funzioni per trasformare tutti i caratteri da maiuscolo in minuscolo e viceversa
(LOWER ed UPPER), di trasformare in maiuscolo solo il primo carattere ed in
minuscolo gli altri (INITCAP), ed altre funzioni meno frequenti. A fronte della
necessità di manipolare caratteri è sempre utile consultare un manuale o informarsi
sull’esistenza di una valida soluzione.
69
4.10
INFN Laboratori Nazionali di Frascati
Quesiti
1) Questa query è corretta?
SQL> Select count(cognome) from caratteri;
2) E quest’altra?
SQL> Select sum(cognome) from caratteri;
3) Supponendo che NOME e COGNOME siano due colonne separate, quali
operatori o funzioni sono in grado di unirle in un’unica colonna?
4) Che cosa significa se il risultato di questa query è 6?
SQL> Select count(*) from TEAMSTATS;
5) Questa funzione è corretta?
SQL> Select SUBSTR COGNOME, 1, 5 from TAB_NOME;
70
4.10
INFN Laboratori Nazionali di Frascati
Esercizi
1) Calcola totale degli impegni di competenza
nome tabella: infn03.cmov2
condizione:
RESID = 0
CAPIT=104020
2) Calcola il numero di variazioni
nome tabella: infn03.cmov3
condizione:
RESID = 1
sui capitoli residui
3) Calcola
quale è l’importo più alto tra le variazioni sia di
competenza che relative ai residui:
nome tabella: infn03.cmov3
71
5
Le clausole di SQL
INFN Laboratori Nazionali di Frascati
Questo capitolo è dedicato alle clausole utilizzate dall’istruzione SELECT del
linguaggio SQL, in particolare a:





WHERE
STARTING WITH
ORDER BY
GROUP BY
HAVING
Per avere un’idea sull’impuego di queste clausole esaminiamo la sintassi
generela:
SELECT [DISTINCT | ALL] { *
| { [schema.[tabella | view | snapshot}.*
| espr } [ [AS] c_alias ]
[, { [schema.]tabella}.*
| espr } [ [AS] c_alias ] ]…...
FROM [schema.]{tabella } [, [schema.]{tabella}
[WHERE condizione]
GROUP BY espr [, espr]…. [HAVING condizione]
[{UNION | UNION ALL | INTERSECT | MINUS | SELECT comando]
[ORDER BY {espr | posizione} [ASC] | [DESC]
[, {espr | posizione} [ASC] [DESC]
72
5.1
INFN Laboratori Nazionali di Frascati
La clausola WHERE
Utilizzando soltanto la clausola SELECT e FROM la query seleziona tutte le
righe di una tabella, ad esempio:
SQL> SELECT * FROM ASSEGNI
ASSEGNO
BENEFICIARIO
IMPORTO
1
Computer Shop
1500.00
Dischetti e CD-Rom
2
Librerie Riunite
2453.40
Libri, cancelleria
3
Computer Shop
2003.20
Telefono cellulare
4
BIOGAS srl
5
SuperMarket GC
6
Assicurazioni Italy
250.00
Assicurazione casa
7
GAS Auto S.p.A.
251.00
Gas
980.00
1500.00
NOTE
Gas
Alimentari
Con la clausola SELECT è possibile essere più selettivi:
SQL> SELECT * FROM ASSEGNI WHERE IMPORTO > 1000.00;
ASSEGNO
BENEFICIARIO
IMPORTO
NOTE
1
Computer Shop
1500.00
Dischetti e CD-Rom
2
Librerie Riunite
2453.40
Libri, cancelleria
3
Computer Shop
2003.20
Telefono cellulare
5
SuperMarket GC
1500.00
Alimentari
La clausola WHERE ha restituito solo i quattro record della tabella ASSEGNI
che soddisfano la condizione richiesta
73
5.1
La clausola WHERE
INFN Laboratori Nazionali di Frascati
La clausola WHERE può risolvere anche altri problemi. Ad esempio data la
tabella di nomi e luoghi è possibile porre la domanda:” Laura dov’è?”
SQL> SELECT * FROM PUZZLE
NOME
LUOGO
TANIA
CORTILE
MARCO
CUCINA
SILVIO
BAGNO
PIPPO
GARAGE
LAURA
SOGGIORNO
ARMANDO
TERRAZZA
SQL> SELECT LUOGO AS "LAURA DOV'E'?"
FROM PUZZLE
WHERE NOME = 'LAURA'
LAURA DOV’E’?
SOGGIORNO
Questa query dimostra che la colonna utilizzata nella condizione dell’istruzione
WHERE non deve essere necessariamente citata nella clausola SELECT
Dopo SELECT e FROM, WHERE è il terzo termine più usato nel linguaggio SQL
74
5.1
INFN Laboratori Nazionali di Frascati
La clausola STARTING WITH
La clausola STARTING WITH è un’aggiunta alla clausola WHERE che opera esattamente
come LIKE(<espr>%). Confrontiamo i risultati delle seguenti query:
SQL> SELECT BENEFICIARIO, IMPORTO, NOTE
FROM ASSEGNI
WHERE BENEFICIARIO LIKE(‘Co%’);
ASSEGNO
BENEFICIARIO
IMPORTO
NOTE
1
Computer Shop
1500.00
Dischetti e CD-Rom
3
Computer Shop
2003.20
Telefono cellulare
SQL> SELECT BENEFICIARIO, IMPORTO, NOTE
FROM ASSEGNI
WHERE BENEFICIARIO STARTING WITH(‘Co%’);
ASSEGNO
BENEFICIARIO
IMPORTO
NOTE
1
Computer Shop
1500.00
Dischetti e CD-Rom
3
Computer Shop
2003.20
Telefono cellulare
I risultati sono identici. Le due clausole possono essere usate insieme
NON AS/400
75
5.1
INFN Laboratori Nazionali di Frascati
La clausola STARTING WITH
SQL> SELECT BENEFICIARIO, IMPORTO, NOTE
FROM ASSEGNI
WHERE BENEFICIARIO STARTING WITH(‘Co%’)
OR NOTE LIKE ‘A%’;
ASSEGNO
BENEFICIARIO
IMPORTO
1
Computer Shop
1500.00
Dischetti e CD-Rom
3
Computer Shop
2003.20
Telefono cellulare
5
SuperMarket GC
1500.00
Alimentari
6
Assicurazioni Italy
250.00
NOTE
Assicurazione casa
La clausola STARTING WITH è comune a molte implementazioni SQL, prima
di innamorarvi dei questa clausola consultare la documentazione
allegata alla versione SQL in uso (OK su Oracle No su AS/400).
NON AS/400
76
5.4
INFN Laboratori Nazionali di Frascati
La clausola ORDER BY
Molto spesso è utile o necessario presentare i risultati si una query in un certo ordine.
Le clausole SELECT e FROM ritornano dati secondo l’ordine di chiave primaria (se
prevista) o nell’ordine in cui i dati sono stati inseriti nel database.
La clausola ORDER BY consente di ordinare le righe ottenute da una query.
Esempio:
SQL> SELECT *
FROM ASSEGNI
ORDER BY ASSEGNO;
ASSEGNO
BENEFICIARIO
IMPORTO
1
Computer Shop
1500.00
Dischetti e CD-Rom
2
Librerie Riunite
2453.40
Libri, cancelleria
3
Computer Shop
2003.20
Telefono cellulare
4
BIOGAS srl
5
SuperMarket GC
6
Assicurazioni Italy
250.00
Assicurazione casa
7
GAS Auto S.p.A.
251.00
Gas
980.00
1500.00
ORDER richiede sempre BY (BY non è facoltativo)
NOTE
Gas
Alimentari
77
5.4
INFN Laboratori Nazionali di Frascati
La clausola ORDER BY
E’ possibile ordinare I record in senso inverso
SQL> SELECT *
FROM ASSEGNI
ORDER BY NUM DESC;
NUM
BENEFICIARIO
IMPORTO
7
GAS Auto S.p.A.
251.00
Gas
6
Assicurazioni Italy
250.00
Assicurazione casa
5
SuperMarket GC
4
BIOGAS srl
3
Computer Shop
2003.20
Telefono cellulare
2
Librerie Riunite
2453.40
Libri, cancelleria
1
Computer Shop
1500.00
Dischetti e CD-Rom
1500.00
980.00
NOTE
Alimentari
Gas
La parola chiave DESC consente di definire l’ordine discendente, ASC è la
parola chiave per il consueto ordine ascendente, ma è raramente usata
poichè rappresenta il valore di default
78
5.4
INFN Laboratori Nazionali di Frascati
La clausola ORDER BY
La clausola ORDER BY può essere applicata a più campi:
SQL> SELECT *
FROM ASSEGNI
ORDER BY BENEFICIARIO, ASSEGN;
NUM
BENEFICIARIO
IMPORTO
NOTE
6
Assicurazioni Italy
250.00
Assicurazione casa
4
BIOGAS srl
980.00
Gas
1
Computer Shop
1500.00
Dischetti e CD-Rom
3
Computer Shop
2003.20
Telefono cellulare
7
GAS Auto S.p.A.
251.00
2
Librerie Riunite
2453.40
Libri, cancelleria
5
SuperMarket GC
1500.00
Alimentari
Gas
Come era facilmente immaginabile il risultato è di avere record ordinati per
beneficiario e nell’ambito di ogni beneficiario per numero.
Se lo si desidera si può anche indicare la colonna anzichè per nome, per numero
(ovviamente deve essere il numero corrispondente alla posizione delle colonne dichiarate)
79
5.5
La clausola GROUP BY
INFN Laboratori Nazionali di Frascati
Abbiamo visto gli operatori aggregati (COUNT – SUM – MIN – MAX etc), ma se volessimo
avere aggregazioni raggruppate per sottoinsiemi dei dati selezionati?
Esempio:
SQL> SELECT BENEFICIARIO, SUM(IMPORTO)
FROM ASSEGNI
GROUP BY BENEFICIARIO;
BENEFICIARIO
IMPORTO
Computer Shop
3503.20
Librerie Riunite
2453.40
BIOGAS srl
980.00
SuperMarket GC
1500.00
Assicurazioni Italy
250.00
GAS Auto S.p.A.
251.00
SQL> SELECT BENEFICIARIO, COUNT (BENEFICIARIO) NUMOPE, SUM(IMPORTO)
FROM ASSEGNI
BENEFICIARIO
NUMOPE
IMPORTO
GROUP BY BENEFICIARIO;
Computer Shop
2
3503.20
Librerie Riunite
1
2453.40
BIOGAS srl
1
980.00
SuperMarket GC
1
1500.00
Assicurazioni Italy
1
250.00
GAS Auto S.p.A.
1
251.00
80
5.5
INFN Laboratori Nazionali di Frascati
La clausola GROUP BY
Esempio
Indicare per consegnatario il numero e l’ammontare del valore dei beni patrimoniali in
carico (nome tabella: infn03.invgen)
SQL> SELECT consegn Consegnatario,
count(consegn) NumeroBeni,
(SUM(valcar) - SUM(valsca)) ValoreBeni
FROM infn03.invgen
GROUP BY consegn
ORDER BY Consegnatario;
Consegnatario
NumeroBeni
ValoreBeni
AGOSTINI E.
10
5983,13
ALBICOCCO M.
36
93716,50
ANTIDORMI S.
9
8467,20
69
147152,49
ANTIDORMI SANDRO
81
5.5
INFN Laboratori Nazionali di Frascati
La clausola GROUP BY
Cosa accade se la clausola GROUP BY specifica più colonne?
SQL> SELECT consegn Consegnatario,
count(consegn) NumeroBeni,
(SUM(valcar) - SUM(valsca)) ValoreBeni
FROM infn03.invgen
GROUP BY ubicaz, consegn
ORDER BY consegn;
Consegnatario
NumeroBeni
ValoreBeni
10
5983,13
ALBICOCCO M.
1
10796,36
ALBICOCCO M.
34
82843,19
ALBICOCCO M.
1
76,95
ANTIDORMI S.
9
8467,20
ANTIDORMI SANDRO
1
5127,18
ANTIDORMI SANDRO
20
10955,70
ANTIDORMI SANDRO
48
131069,61
AGOSTINI E.
10
5983,13
AGOSTINI E.
82
5.5
La clausola GROUP BY
INFN Laboratori Nazionali di Frascati
Osserviamo la seguente query:
SQL> SELECT consegn, valcar, count(valcar)
FROM infn03.invgen GROUP BY consegn;
Dynamic SQL Error
-SQL error code = -104
-invalid column reference
SQL non è in grado di eseguire la query; per capire il perchè basta mettersi
per un momento nei panni di SQL. Si supponga di dover raggruppare le
seguenti righe:
SQL> SELECT consegn, ubicaz, valcar
FROM infn03.invgen
WHERE consegn=‘ANTIDORMI SANDRO’;
CONSEGN
UBICAZ
VALCAR
ANTIDORMI SANDRO
Ed. Magazzino
5127,18
ANTIDORMI SANDRO
Ed. Magazzino
10955,70
ANTIDORMI SANDRO
Uff. di direzione
ANTIDORMI SANDRO
Ufficio EDP
131069,61
5983,13
Se avessimo provato a raggrupparle dove cosa avreste scritto come UBICAZIONE?
Avendo una sola riga di riepilogo non possiamo scriverci contemporaneamente più valori
83
5.6
INFN Laboratori Nazionali di Frascati
La clausola HAVING
Come è possibile qualificare i dati utilizzati nella clausola GROUP BY?
Per rispondere sarà usata la tabella ORGCHART
NOME
DIVISIONE
STIPENDIO
CONGEDIMALATTIA
CONGEDIANNUI
ADAMS
RESEARCH
34000.00
34
12
WILKES
MARKETING
31000.00
40
9
STOKES
MARKETING
36000.00
20
19
MEZA
COLLECTIONS
40000.00
30
27
MERRICK
RESEARCH
45000.00
20
17
RICHARDSON
MARKETING
42000.00
25
18
FURY
COLLECTIONS
35000.00
22
14
PRECOURT
PR
37500.00
24
24
Per raggruppare l’output in base alle divisioni e calcolare lo stipendio medio di ogni
divisione, basta scrivere la seguente query:
SQL> SELECT DIVISIONE, AVG(STIPENDIO)
FROM ORGCHART
DIVISIONE
STIPENDIO
GROUP BY DIVISIONE;
COLLECTIONS
37500.00
MARKETING
36333.33
PR
37500.00
RESEARCH
39500.00
84
5.6
INFN Laboratori Nazionali di Frascati
La clausola HAVING
Proviamo a qualificare una query che consente di estrarre soltanto quelle divisioni i cui
stipendi medi sono minori di 38000:
SQL> SELECT DIVISIONE, AVG(STIPENDIO)
FROM ORGCHART
WHERE AVG(STIPENDIO) < 38000
GROUP BY DIVISIONE;
Dynamic SQL Error
-SQL error code = -104
-Invali aggregate reference
Questo errore si verifica perchè WHERE non opera con le funzioni di aggregazione.
Affinché questa query possa operare occorre qualcosa di nuovo: la clausola
HAVING, infatti:
SQL> SELECT DIVISIONE, AVG(STIPENDIO)
FROM ORGCHART
GROUP BY DIVISIONE
HAVING AVG(STIPENDIO) < 38000;
DIVISIONE
STIPENDIO
COLLECTIONS
37500.00
MARKETING
36333.33
PR
37500.00
85
5.6
INFN Laboratori Nazionali di Frascati
La clausola HAVING
La clausola HAVING consente di utilizzare le funzioni aggregate in un’istruzione di
confronto, fornendo alle funzioni aggregate ciò che WHERE fornisce alle singole
righe. La clausola HAVING può operare con le espressioni non aggregate? Proviamo
questa query:
SQL> SELECT DIVISIONE, AVG(STIPENDIO)
FROM ORGCHART
GROUP BY DIVISIONE
WHERE STIPENDIO < 38000;
DIVISIONE
PR
STIPENDIO
37500.00
Come mai questo risultato é diverso dall’ultima query?
86
5.6
La clausola HAVING
INFN Laboratori Nazionali di Frascati
La clausola HAVING AVG(STIPENDIO) >38000 ha valutato i singoli gruppi
ed ha restituito soltanto quelli con uno stipendio medio minore di
38000, proprio ciò che volevamo, invece la clausola HAVING
STIPENDIO<38000 ha prodotto un risultato diverso. In sostanza la
clausola ha valutato tutti gli stipendi escludendo i gruppi in cui anche
un solo stipendio non rientra nella condizione indicata, infatti salvo la
divisione PR in tutte le altre vi è almeno uno stipendio maggiore di
38000.
SQL> SELECT NOME, DIVISIONE, STIPENDIO
FROM ORGCHART
ORDER BY DIVISIONE
NOME
DIVISIONE
STIPENDIO
FURY
COLLECTIONS
35000.00
MEZA
COLLECTIONS
40000.00
WILKES
MARKETING
31000.00
STOKES
MARKETING
36000.00
RICHARDSON
MARKETING
42000.00
PRECOURT
PR
37500.00
ADAMS
RESEARCH
34000.00
MERRICK
RESEARCH
45000.00
Alcune implementazioni SQL restituiscono errore se nella clausola
HAVING non viene utilizzata una funzione aggregata.
87
5.6
INFN Laboratori Nazionali di Frascati
La clausola HAVING
E’ anche possibile utilizzare più condizioni.
Ad esempio:
SQL> SELECT DIVISIONE, AVG(CONGEDMAL), AVG(CONGEDANN)
FROM ORGCHART
GROUP BY DIVISIONE
HAVING AVG(CONGEDMAL) > 25 AND
AVG(CONGEDANN) < 20;
DIVISIONE
AVG
AVG
MARKETING
27
15
RESEARCH
27
15
La query ha restituito tutte le divisioni con medie di CONGEDIMALATTIA
maggiori di 25 giorni e medie di CONGEDIANNUI inferiori a 29
giorni.
88
5.6
La clausola HAVING
INFN Laboratori Nazionali di Frascati
Altri esempi:
SQL> SELECT DIVISIONE, AVG(CONGEDMAL), AVG(CONGEDANN)
FROM ORGCHART
GROUP BY DIVISIONE
HAVING COUNT(DIVISIONE) > 1;
DIVISIONE
AVG
AVG
COLLECTIONS
26
21
MARKETING
28
15
RESEARCH
27
15
SQL> SELECT DIVISIONE, MIN(STIPENDIO), MAX(STIPENDIO)
FROM ORGCHART
GROUP BY DIVISIONE
HAVING AVG(STIPENDIO) > 37000
OR MIN(STIPENDIO) > 32000;
DIVISIONE
MIN
MAX
COLLECTIONS
35000.00
40000.00
PR
37500.00
37500.00
RESEARCH
34000.00
45000.00
89
5.6
INFN Laboratori Nazionali di Frascati
La clausola HAVING
L’operatore IN opera anche nella clausola HAVING:
SQL> SELECT DIVISIONE, AVG(STIPENDIO)
FROM corso.ORGCHART
GROUP BY DIVISIONE
HAVING DIVISIONE IN ('PR', 'RESEARCH');
DIVISIONE
AVG
PR
37500.00
RESEARCH
39500.00
90
5.7
INFN Laboratori Nazionali di Frascati
Combinazione di clausole
Esempio 1
Trovare tutti gli assegni emessi a favore di Computer Shop e per le forniture
del gas ordinandoli in base alla colonna NOTE:
SQL> SELECT BENEFICIARIO, NOTE
FROM ASSEGNI
WHERE BENEFICIARIO = ‘Computer Shop’
or NOTE like(‘Ga%’)
ORDER BY NOTE;
BENEFICIARIO
NOTE
Computer Shop
Controller
Computer Shop
Dischetti e CD-Rom
BIOGAS srl
Gas
GAS Auto S.p.A.
Gas
GAS Auto S.p.A.
Gas
Computer Shop
Joystick
Computer Shop
Telefono cellulare
SELECT BENEF, NOTE
FROM corso.ASSEGNI
WHERE BENEF = 'Computer Shop'
or NOTE like('Ga%')
ORDER BY NOTE;
Con LIKE vengono trovate le note che iniziano con ‘Ga’. Con l’operatore OR
I dati vengono estratti se la clausola WHERE soddisfa una delle due
condizioni
91
5.7
INFN Laboratori Nazionali di Frascati
Combinazione di clausole
Esempio 2
Utilizzando la tabella ORGCHART trovare lo stipendio di quei dipendenti che
hanno meno di 25 giorni di congedi per malattia, ordinando I record
per nome:
SQL> SELECT NOME, STIPENDIO
FROM ORGCHART
WHERE CONGEDOMALATTIA < 25
ORDER BY NOME;
NOME
STIPENDIO
FURY
35000.00
MERRICK
45000.00
PRECOURT
37500.00
STOKES
36000.00
E’ una query semplice che offre l’opportunità di utilizzare insieme la
clausola WHERE e ORDER BY
92
5.7
INFN Laboratori Nazionali di Frascati
Combinazione di clausole
Esempio 3
Utilizzando la tabella ORGCHART elencare gli stipendi medi, la media dei
congedi per malattia e quella dei congedi annui per ogni divisione:
SQL> SELECT DIVISIONE,
AVG(STIPENDIO),
AVG(CONGEDIMALATTIA),
AVG(CONGEDIANNUI)
FROM ORGCHART
GROUP BY DIVISIONE;
DIVISIONE
AVG
AVG
AVG
COLLECTIONS
37500.00
26
21
MARKETING
36333.33
28
15
PR
37500.00
24
24
RESEARCH
39500.00
26
15
93
5.7
Combinazione di clausole
INFN Laboratori Nazionali di Frascati
Segue una interessante variante della query precedente, proviamo a
spiegarne I risultati ottenuti:
SQL> SELECT DIVISIONE,
AVG(STIPENDIO), AVG(CONGEDIMALATTIA, AVG(CONGEDIANNUI)
FROM ORGCHART GROUP BY DIVISIONE ORDER BY NOME;
DIVISIONE
AVG
AVG
AVG
RESEARCH
39500.00
26
15
COLLECTIONS
37500.00
26
21
PR
37500.00
24
24
MARKETING
36333.33
28
15
Una query più semplice potrebbe dare suggerimenti:
SQL> SELECT NOME, DIVISIONE
FROM ORGCHART ORDER BY NOME;
NOME
DIVISIONE
ADAMS
RESEARCH
FURY
COLLECTIONS
MERRICK
RESEARCH
MEZA
COLLECTIONS
PRECOURT
PR
RICHARDSON
MARKETING
STOKES
MARKETING
WILKES
MARKETING
94
5.8
INFN Laboratori Nazionali di Frascati
Quesiti
1.
Quale clausola opera come LIKE(<espr>%)?
2.
Quale è la funzione della clausola GROUP BY e quale altra clausola
opera in modo analogo?
3.
E’ corretta questa istruzione SELECT:
SELECT NOME, AVG(STIPENDIO), DIPARTIMENTO
FROM TAB_STIP
WHERE DIPARTIMENTO = ‘PERSONALE’
ORDER BY NOME
GROUP BY DIPARTIMENTO, STIPENDIO
Quando si usa la clausola HAVING, è necessario usare anche GROUP
BY?
E’ possibile applicare ORDER BY a una colonna che non è inclusa tra
quelle citate nella clausola SELECT?
4.
5.
95
5.9
INFN Laboratori Nazionali di Frascati
Esercizi
1.
Utilizzando la tabella ORGCHART dei precedenti esempi, trovare qunti
dipendenti di ogni divisione hanno 30 o più giorni di congedi per
malattia.
2.
Utilizzando la tabella ASSEGNI, scrivere una istruzione SELECT per
ottenere il seguente risultato:
ASSEGNO
1
BENEFICIARIO
IMPORTO
Computer Shop
1500.00
96
6.0
Combinazione di tabelle e subquery
INFN Laboratori Nazionali di Frascati
Obiettivi:

Leggere e manipolare dati che si trovano in più tabelle

Creare un subquery (collegare una query al risultato di un’altra
query)
97
6.1 Più tabelle in una sola
INFN Laboratori Nazionali di Frascati
SELECT
SELECT * FROM TABELLA1
RIGA
SELECT * FROM TABELLA1
NOTE
RIGA
NOTE
1
Nota 1 tabella 1
1
Nota 1 tabella 2
2
Nota 2 tabella 1
2
Nota 2 tabella 2
3
Nota 3 tabella 1
3
Nota 3 tabella 2
SELECT * FROM TABELLA1, TABELLA 2
RIGA
NOTE
RIGA
NOTE
1
Nota 1 tabella 1
1
Nota 1 tabella 2
1
Nota 1 tabella 1
2
Nota 2 tabella 2
1
Nota 1 tabella 1
3
Nota 3 tabella 2
2
Nota 2 tabella 1
1
Nota 1 tabella 2
2
Nota 2 tabella 1
2
Nota 2 tabella 2
2
Nota 2 tabella 1
3
Nota 3 tabella 2
3
Nota 3 tabella 1
1
Nota 1 tabella 2
3
Nota 3 tabella 1
2
Nota 2 tabella 2
3
Nota 3 tabella 1
3
Nota 3 tabella 2
tabella2
tabella1
Tabella
risultante
9 righe? Da dove arrivano? Un esame più attento indica che
sono state indicate tutte le righe della tabella 1 per ogni
riga della tabella 2
98
6.1
INFN Laboratori Nazionali di Frascati
Più tabelle in una sola SELECT
Abbiamo ottenuto una combinazione chiamata cross-join (unione incrociata), non
è particolarmente utile ma illustra ciò che sta alla base del concetto di join.
Un database relazionale correttamente progettato dstribuisce su più tabelle le
informazioni, raggruppandole per gruppi omogenei, ad esempio:
ORDINI
Num Ditta
Descrizione
Totale
1
CENTRO GAS S.R.L.
1500 LT.G.P.L.PROPANO
972,00
2
PISCITELLI ANTONIO VIAGGI
TRASPORTO ISPETTORI IN VISITA
115,50
3
COOPERATIVA A.C.F.
SERVIZIO MICROFONI FORO GLOBAL
54,00
4
GHIZZONI SERAFINO
NOLEGGIO PULMINI VISITE
79,20
5
CIVICO 11 STUDIO GRAFICO
PROG.GRAFICA MANIFESTO
238,61
RIGHEORDINI
Num
Quantita
1
1500
2
1
2
Descrizione
Prezzo
IVA
5,4
20
minubus 16 posti
600,0
10
3
ore attesa
150,0
10
3
3
ore lavoro per servizio microfoni sala
150,0
20
3
0
Majorana per il 23 gennaio 2003
0
20
4
1
noleggio n. 2 pulmini per visite
720,0
10
4
0
partecipanti meeting di auger
0
20
lt. di g.p.l. propano per lab.esterni
Come combinare opportunamente le due tabelle?
99
Più tabelle in una sola
6.1 SELECT
INFN Laboratori Nazionali di Frascati
Per combinare opportunamente due o più tabelle è utile la clausola WHERE, ad esempio:
SELECT a.numpar, a.ordi1, b.qtarig, b.desrig, b.preuni * 0.01
FROM infn03.cord1 as a, infn03.cord2 as b
WHERE a.numpar =b.numpar
Numpar
ordI1
QTARIG
DESRIG
1500
PREUNI
1
CENTRO GAS S.R.L.
lt. di g.p.l. propano per lab.esterni
0,54
2
PISCITELLI ANTONIO VIAGGI
1
minubus 16 posti
60,00
2
PISCITELLI ANTONIO VIAGGI
3
ore attesa
15,00
3
COOPERATIVA A.C.F.
3
ore lavoro per servizio microfoni sala
15,00
3
COOPERATIVA A.C.F.
0
Majorana per il 23 gennaio 2003
4
GHIZZONI SERAFINO
1
noleggio n. 2 pulmini per visite
4
GHIZZONI SERAFINO
0
partecipanti meeting di auger
5
CIVICO 11 STUDIO GRAFICO
1
ideazione progettazione grafica e
5
CIVICO 11 STUDIO GRAFICO
0
videoimpaginazione di n. 1 manifesto
0
72,00
0
198,84
0
Abbiamo ridenominato a la tabella infn03.cord1 e b la tabella infn03.cord2, quindi
abbiamo operato sulle righe risultanti operando una combinazione
corrispondente (colonna NUMPAR presente in entrambe le tabelle).
Se non avessimo usato la clausola WHERE il risultato sarebbe stato di attente il
numero di righe della prima tabella moltiplicato il numero della seconda.
Quindi, salvo non si desideri davvero una combinazione cartesiana (x * y) è
sempre consigliabile l’uso della clausola WHERE.
100
6.2
INFN Laboratori Nazionali di Frascati
Subquery
La sintassi è abbastanza semplice: SELECT x, y from z WHERE a = (select a from b
where c = condizione).
Esempio:
select b.preute, a.capit, a.cprass * 0.01 ASSEGN, a.cprimp * 0.01 IMPEGN,
a.cprass * 0.01 - a.cprimp * 0.01 DISPON
from infn03.ccpr a, infn03.cpre b
where a.preven=b.preven
and a.PREVEN = (SELECT preven
from infn03.Cpre
where PREUTE='AMM.NE')
PREUTE
CAPIT
ASSEGN
IMPEGN
DISPON
AMM.NE
104020
2000,00
500,00
1500,00
AMM.NE
212010
1076,18
376,18
700,00
E’ ovviamente possibile usare nella subquery tutte le funzioni che ritornano un
valore coerente con la clausola principale WHERE
101
6.2
Subquery annidate
INFN Laboratori Nazionali di Frascati
Con il termine annidamento si intende l’operazione con la quale una subquery
viene incorporata all’interno di un’altra subquery:
Select * from qualcosa where (subquery(subquery(subquery)));
Il numero degli annidamenti variano a seconda dell’implementazione SQL
Quando si ha necessità di avere più valori di ritorno da una subquery si
può ricorrere alla parola chiave IN:
select b.preute, a.capit, a.cprass * 0.01, a.cprsj * 0.01 , a.cprimp * 0.01,
a.cprcgl * 0.01 , a.cngsj * 0.01
from infn03.ccpr a, infn03.cpre b
where a.preven=b.preven and a.PREVEN in
(SELECT preven from infn03.Cpre where preven like ’44%’)
102
6.2
INFN Laboratori Nazionali di Frascati
Subquery e operatore IN
select b.preute, a.capit, a.cprass * 0.01, a.cprsj * 0.01 ,
a.cprimp * 0.01, a.cprcgl * 0.01 , a.cngsj * 0.01
from infn03.ccpr a, infn03.cpre b where a.preven=b.preven and a.PREVEN in
(SELECT preven from infn03.Cpre where preven like ’44%’)
PREUTE
CAPIT
CPRASS
CPRSJ
CPRIMP
CPRCGL
CNGSJ
DOT.GR.IV
102060
12500,00
0
7058,40
0
0
DOT.GR.IV
102061
5000,00
0
1050,00
0
0
DOT.GR.IV
102070
11500,00
0
3794,69
0
0
DOT.GR.IV
104020
10000,00
0
6863,62
0
0
DOT.GR.IV
104030
21000,00
0
4729,09
0
0
DOT.GR.IV
212010
16000,00
0
2787,60
0
0
FA51
102060
500,00
0
0
0
0
FA51
102070
1000,00
0
0
0
0
GI31
102060
1000,00
0
573,86
0
0
LF11
102060
5000,00
0
2027,70
0
0
LF11
102061
11000,00
0
2000,00
0
0
LF11
102070
14000,00
0
1600,00
0
0
LF21
102060
1500,00
0
1589,05
0
0
LF21
102061
2500,00
0
1696,98
0
0
LF21
102070
3000,00
0
1311,85
0
0
MI11
102060
1500,00
0
598,12
0
0
103
6.2
Subquery
INFN Laboratori Nazionali di Frascati
select substring(preven,1,2) RifProgr, capit, sum(cprass * 0.01) ASSEGN,
sum(cprimp * 0.01)IMPEGN, sum(cprass * 0.01) - sum(cprimp * 0.01) DISPON
from infn03.ccpr group by substring(preven,1,2), capit
having substring(preven,1,2) in
(SELECT substring(preven,1,2) from infn03.Cpre where preven like '44%')
Order by capit
RifPRogr
CAPIT
ASSEGN
IMPEGN
DISPON
44
102060
29000,00
15008,28
13991,72
44
102061
31500,00
4746,98
26753,02
44
102070
45500,00
11240,05
34259,95
44
104020
10000,00
6863,62
3136,38
44
104030
21000,00
4729,09
16270,91
44
212010
16000,00
2787,60
13212,40
select substring(preven,1,2)RifProgr, capit, sum(cprass * 0.01)ASSEGN, sum(cprimp *
0.01)IMPEGN , sum(cprass * 0.01) - sum(cprimp * 0.01) DISPON
from infn03.ccpr group by substring(preven,1,2), capit having substring(preven,1,2)='44'
order by capit
104
6.2
INFN Laboratori Nazionali di Frascati
Subquery e operatore IN
select b.preute, a.capit, sum(a.cprass * 0.01), sum(a.cprimp * 0.01)
from infn03.ccpr a, infn03.cpre b
where a.preven=b.preven and a.PREVEN in
(SELECT preven from infn03.Cpre where preven like ‘44%’)
Group by preute, capit
Order by preute, capit
PREUTE
CAPIT
CPRASS
CPRIMP
DOT.GR.IV
102060
12500,00
7058,40
DOT.GR.IV
102061
5000,00
1050,00
DOT.GR.IV
102070
11500,00
3794,69
DOT.GR.IV
104020
10000,00
6863,62
DOT.GR.IV
104030
21000,00
4729,09
DOT.GR.IV
212010
16000,00
2787,60
FA51
102060
500,00
0
FA51
102070
1000,00
0
GI31
102060
1000,00
573,86
105
6.10 Quesiti
INFN Laboratori Nazionali di Frascati
1.
Quante righe produce la combinazione di due tabelle che hanno rispettivamente
50.000 e 100.000 righe?
2.
Che tipo di combinazione genera la seguente istruzione SELECT?
SELECT ti.nome, ti.id_impiegato, ts.stipendio
FROM tabella_impiegati ti, tabella_stipendi ts
WHERE ti.id_impiegato = ts.id_impiegato;
3.
Sono corrette le seguenti istruzioni SELECT?
a.
SELECT nome, id_impegato, stipendio
FROM tabella_impiegati ti, tabella_stipendi ts
WHERE id_impegato = id_impiegato
and nome like ’%SMITH’;
b.
SELECT ti.nome, ti.id_impiegato, ts.stipendio
FROM tabella_impiegati ti, tabella_stipendi ts
WHERE nome like ’%SMITH’;
c.
SELECT ti.nome, ti.id_impiegato, ts.stipendio
FROM tabella_impiegati ti, tabella_stipendi ts
WHERE ti.id_impiegato = ts.id_impiegato
and ti.nome like ’%SMITH’;
4.
Per unire due tabelle, nella clausola WHERE occorre prima combinare le tabelle o
specificare le condizioni?
Le combinazioni delle tabelle possono essere effettuate sulla base di una sola
colonna o di più colonne?
5.
106
6.11 Esercizi
INFN Laboratori Nazionali di Frascati
1.
Nel paragrafo dedicato alla combinazione di una tabella con se stessa, l’ultimo
esempio ha fornito due combinazioni. Riscrivere la query in modo che venga
fornita una sola voce per ogni numero di parte duplicato.
2.
Riscrivere la seguente query per renderla più breve e leggibile.
SELECT ordini.ordinatoil, ordini.nome, parti.numparte, parti.prezzo,
parti.descrizione from ordini, parti where ordini.numparte = parti.numparte
and ordini.ordinatoil between ‘1-sep-96’ and ’30-sep-96’ order by
parti.numparte;
3.
Utilizzando le tabelle PARTI e ORDINI, scrivere una query per estrarre I seguenti
dati:
ORDINATOIL
NOME
NUMPARTE
QUANTITY
2-SEP-96
TRUE WHEEL
10
1
107
6.2
Esempi RIEPILOGATIVI
INFN Laboratori Nazionali di Frascati
Timbrature da Storico del badge n. 1685 relative al mese di giugno 2003:
select a.nome, a.badge, b.ANNO, b.MESE, b.GIORNO, b.HHMM, b.CAUSAL, b.EU
from pers03.anasrp as a, libsele400.storico as b
where a.badge = concat ('0', substr(DIGITS(b.badge),1,4))
and b.badge = 1685 and b.anno = 03 and b.mese = 06
NOME
BADGE
ANNO
MESE
GIORNO
JJMM
CAUSAL
EU
ANTIDORMI SANDRO
01685
3
6
3
840
0
0
ANTIDORMI SANDRO
01685
3
6
3
1456
0
1
ANTIDORMI SANDRO
01685
3
6
4
851
0
0
ANTIDORMI SANDRO
01685
3
6
4
1854
0
1
ANTIDORMI SANDRO
01685
3
6
5
840
0
0
ANTIDORMI SANDRO
01685
3
6
5
1901
0
1
ANTIDORMI SANDRO
01685
3
6
6
929
0
0
ANTIDORMI SANDRO
01685
3
6
6
1735
0
1
ANTIDORMI SANDRO
01685
3
6
9
838
0
0
ANTIDORMI SANDRO
01685
3
6
9
1640
0
1
108
6.2
Esempi RIEPILOGATIVI
INFN Laboratori Nazionali di Frascati
La seguente query serve per calcolare il totale per capitolo degli impegni iniziali
(senza variazioni) assunti con data minore di aprile 2003 (fino a tutto
marzo):
select sum(carim2) totaleImpegni from infn03.cmov2
where mmm2<4 and aam2=3 and GESTIO = 0
and sospes=0 and eu = 0 and capit = 104230 and AIPAR = 'I'
Totale impegni
7382174
Quest’altra consente di tirar fuori il totale di tutti gli impegni iniziali di
competenza relativo ai primi tre mesi del 2003:
Select sum(carim2) ImpegniIniziali from infn03.cmov2
where mmm2<4 and aam2=3 and GESTIO = 0 and sospes=0
and eu = 0 and substr(DIGITS(CAPIT),3,1) = '4' and AIPAR = 'I'
ImpegniIniziali
699561044
109
6.2
Esempi RIEPILOGATIVI
INFN Laboratori Nazionali di Frascati
la seguente istruzione consente di estrarre il totale per capitolo delle
assegnazioni relative ai criteri finora seguiti(nota bene dopo
sum(carim2)*0.01 as SSEGANZIONI serve per mettere i decimali, cioe'
divide pre cento ed intestare la colonna):
Select capit, sum(carim2)*0.01 as ASSEGNAZIONI
from infn03.cmov2
where mmm2<4 and aam2=3 and GESTIO = 0 and sospes=0 and eu = 0
and substr(DIGITS(CAPIT),3,1) = '4' and AIPAR = 'A' group by capit
CAPIT
ASSEGNAZIONI
104020
6478500,00
104170
2500000,00
104010
5000,00
104210
14500,00
104040
10500,00
104070
5000,00
104110
308000,00
104190
150000,00
104060
57000,00
104180
180000,00
110
6.2
Esempi RIEPILOGATIVI
INFN Laboratori Nazionali di Frascati
Esempio di semplice estrazione dati patrimonio (INVGEN) selezionando solo
beni ‘V’ e con consegnatario che si chiama …..IAC…. in ordine alfabetico
assegnatario:
SELECT NUMINV, AANOT, NUMNOT, DATARRIV, DESCR1, DENOM1, CONSEGN, VALCAR
FROM INFN03.INVGEN
WHERE TIPOBENE = 'V' AND CONSEGN LIKE'%IAC%'
ORDER BY CONSEGN
NUMINV
AANOT
NUMNOT
DATARRIV
DESCR1
9355
1993
119
1993-03-19
STAMPANTE H.P. MOD.3630A.SN3219A00160
2344
1989
257
1989-05-31
BANCO DA LAVORO COD.14450
9910
1988
24
1988-02-22
BANCO DA LAVORO BOTT.ART.FW11
9911
1992
134
1992-03-11
9912
1989
475
9913
1989
9914
DENOM1
HEWLETT PACKARD ITALIANA
S.P.A.
CONSEGN
VALCAR
GIACINTI O.
861,95
IACUESSA E.
586,07
UTENSIL MECCANICA S.N.C.
IACUESSA E.
953,74
LAMPADE DA TAVOLO ART 114
TECNICHE INDUSTRIALI SRL
IACUESSA E.
27,66
1989-11-13
SEGHETTO ALTERNATIVO METABO
ST450
CESARE UBOLDI S.P.A.
IACUESSA E.
85,43
475
1989-11-13
SMERIGLIATRICE METABO EX6114S
CESARE UBOLDI S.P.A.
IACUESSA E.
107,55
1989
475
1989-11-13
SEGA CIRCOLARE METABO K.S. 0852-S
CESARE UBOLDI S.P.A.
IACUESSA E.
136,44
9915
1991
9
1991-02-12
TRAPANO AVVITATORE BOSCH-GSR-
UTOR S.R.L.
IACUESSA E.
187,54
9916
1991
9
1991-02-12
TRAPANO BOSCH GSR. SN.0601930727
UTOR S.R.L.
IACUESSA E.
164,03
9355
1993
119
1993-03-19
STAMPANTE H.P. MOD.3630A.SN3219A00160
HEWLETT PACKARD ITALIANA
S.P.A.
GIACINTI O.
861,95
111
6.2
Esempi RIEPILOGATIVI
INFN Laboratori Nazionali di Frascati
Esempio di estrazione timbrature da storico
select a.nome, a.badge , b.ANNO, b.MESE, b.GIORNO, b.HHMM, b.CAUSAL, b.EU
from pers03.anasrp as a, libsele400.storico as b
where a.badge = '0' concat substr(DIGITS(b.badge),1,4) and a.badge = 1685 and
b.anno=03
nome
badge
Anno
Mese
Giorno
Hmm
Causal
eu
ANTIDORMI SANDRO
01685
3
1
7
1156
0
0
ANTIDORMI SANDRO
01685
3
1
7
2000
0
1
ANTIDORMI SANDRO
01685
3
1
8
1159
0
0
ANTIDORMI SANDRO
01685
3
1
8
2000
0
1
ANTIDORMI SANDRO
01685
3
1
9
1234
0
0
ANTIDORMI SANDRO
01685
3
1
9
2000
0
1
ANTIDORMI SANDRO
01685
3
1
10
1026
0
0
ANTIDORMI SANDRO
01685
3
1
10
2000
0
1
ANTIDORMI SANDRO
01685
3
1
13
658
0
0
ANTIDORMI SANDRO
01685
3
1
13
1453
0
1
112
6.2
Esempi RIEPILOGATIVI
INFN Laboratori Nazionali di Frascati
Costruzione grafico consumi mensili categoria IV
SELECT MMM2, SUM(CARIM2) FROM INFN02.CMOV2
WHERE AIPAR = 'I'AND EU = 0 AND GESTIO = 0
AND SOSPES = 0 AND SUBSTR(DIGITS(CAPIT),3,1) = '4'
GROUP BY MMM2
ORDER BY MMM2
SELECT MMVAR, SUM(IMPVAR) FROM INFN02.CMOV3
WHERE AIPAR = 'I' AND EU = 0 AND GESTIO = 0
AND SOSPES = 0 AND SUBSTR(DIGITS(CAPIT),3,1) = '4'
GROUP BY MMVAR
ORDER BY MMVAR
CATEGORIA IV (BENI DI CONSUMO)
IMPEGNI MENSILI 2002
MESE ASSEGNAZIONI
IMPEGNI
VARIAZ TOT IMPEGNI
quadrimestre
113
6.2
Esempi RIEPILOGATIVI
INFN Laboratori Nazionali di Frascati
Costruzione grafico consumi mensili categoria IV
GEN
FEB
MAR
APR
MAG
GIU
LUG
AGO
SET
OTT
NOV
DIC
1
CATEGORIA IV
114
SQL
CONSEGN
SELECT DISTINCT(CONSEGN)
FROM infn03.invgen
ORDER BY consegn;
ABATE EMILIO
ABENANTE MASSIMO
ANTIDORMI S.
ANTIDORMI SANDRO
SANDRO ANTIDORMI
…
…
Altri nomi
UPDATE infn03.invgen
SET CONSEGN = ‘ANTIDORMI SANDRO’
WHERE consegn LIKE ‘%ANTIDORMI%’
Il risultato è quello di avere come
assegnatario “ANTIDORMI SANDRO” in tutti
record della tabella nei quali risulta la
presenza della stringa “ANTIDORMI”
Scarica

Corso di SQL