SQL [2] Concetti avanzati di SQL 2 Esempi di interrogazioni
3 Esempi di interrogazioni 4 Esempi di interrogazioni
5 Confronti che coinvolgono NULL NULL può voler dire: valore sconosciuto (esiste ma non è noto) Esempio: La data di nascita di una persona: esiste sicuramente ma non si conosce. valore non disponibile (intenzionalmente non fornito) Esempio: Una persona ha un numero telefonico di casa ma non vuole che sia registrato. non applicabile (indefinito per questa tupla) Esempio: un attributo LAUREA per una persona che non è laureata. 6 Confronti che coinvolgono NULL SQL non distingue fra i tre significati di NULL. Nella base di dati ciascun valore NULL è considerato differente da ogni altro NULL. Quando NULL è coinvolto in un operazione di confronto il risultato è considerato UNKNOWN SQL usa una logica a tre valori: TRUE FALSE UNKNOWN
7 Connettivi logici, nella logica a 3 valori 8 Interrogazione 14 Si trovino i nomi di tutti gli impiegati che non hanno supervisori. SELECT NOME_BATT, COGNOME FROM IMPIEGATO WHERE SUPER_SSN IS NULL; SQL usa IS o IS NOT per confrontare il valore di un attributo con NULL Non può usare = perché ogni NULL è differente
9 Interrogazioni nidificate Alcune interrogazioni richiedono di estrarre alcuni valori esistenti nella base di dati per poi usarli in una condizione di confronto. Le interrogazioni nidificate sono blocchi completi select-from-where posti all interno della clausola WHERE di un altra interrogazione (detta interrogazione esterna). 10 Interrogazione 15 (come la 8 per Wong ) Si crei un elenco di tutti i numeri di progetto dei progetti che coinvolgono un dipendente il cui cognome è Smith, come partecipante oppure come dirigente del dipartimento che controlla il progetto. SELECT DISTINCT NUMERO_P FROM PROGETTO WHERE NUMERO_P IN (SELECT NUMERO_P FROM PROGETTO, DIPARTIMENTO, IMPIEGATO WHERE NUM_D=NUMERO_D AND SSN_DIR=SSN AND COGNOME = Smith ) OR NUMERO_P IN (SELECT N_P FROM LAVORA_SU, IMPIEGATO WHERE SSN_I=SSN AND COGNOME = Smith ) L operatore IN confronta un valore v con un insieme (o multinsieme) di valori V, il suo valore è TRUE se v è uno degli elementi in V.
11 Interrogazione 8 Si crei un elenco di tutti i numeri di progetto dei progetti che coinvolgono un dipendente il cui cognome è Wong, come partecipante oppure come dirigente del dipartimento che controlla il progetto. (SELECT DISTINCT NUMERO_P FROM PROGETTO, DIPARTIMENTO, IMPIEGATO WHERE NUM_D=NUMERO_D AND SSN_DIR=SSN AND COGNOME= Wong') UNION (SELECT DISTINCT NUMERO_P FROM PROGETTO, LAVORA_SU, IMPIEGATO WHERE NUMERO_P=N_P AND SSN_I=SSN AND COGNOME= Wong') 12 Livelli di interrogazioni nidificate Si possono avere più livelli di interrogazioni nidificate E possibile che vi sia ambiguità tra i nomi degli attributi I riferimenti ad attributi non qualificati si riferiscono alla relazione dichiarata nell interrogazione nidificata più interna
13 Interrogazione 16 Si trovi il nome di ciascun dipendente che ha una persona a carico con il medesimo nome e lo stesso sesso del dipendente. SELECT I.NOME_BATT, I.COGNOME FROM IMPIEGATO AS I WHERE I.SSN IN (SELECT SSN_I FROM PERSONA_A_CARICO AS C WHERE I.NOME_BATT = C.NOME_PERSONA_A_CARICO AND I.SESSO = C.SESSO) Quando una condizione nella clausola WHERE (di una interrogazione nidificata) fa riferimento ad attributi di una tabella dichiarata (nell interrogazione esterna) si dice che le interrogazioni sono correlate 14 Interrogazione 17 (come la 16) Si trovi il nome di ciascun dipendente che ha una persona a carico con il medesimo nome e lo stesso sesso del dipendente. SELECT I.NOME_BATT, I.COGNOME FROM IMPIEGATO AS I, PERSONA_A_CARICO AS D WHERE I.SSN=D.SSN_I AND I.SESSO = D.SESSO AND I.NOME_BATT = D.NOME_PERSONA_A_CARICO In generale si può sempre esprimere un interrogazione nidificata che fa uso di = o IN con un interrogazione a singolo blocco
15 Interrogazione 18 (come la 16) Si trovi il nome di ciascun dipendente che ha una persona a carico con il medesimo nome e lo stesso sesso del dipendente. SELECT I.NOME_BATT, I.COGNOME FROM IMPIEGATO AS I WHERE EXISTS (SELECT * FROM PERSONA_A_CARICO AS C WHERE I.SSN=C.SSN_I AND I.SESSO = C.SESSO AND I.NOME_BATT = C.NOME_PERSONA_A_CARICO) EXISTS(I) restituisce TRUE se c è almeno una tupla nel risultato dell interrogazione 16 Interrogazione 19 Si trovino i nomi dei dipendenti che non hanno persone a carico. SELECT NOME_BATT, COGNOME FROM IMPIEGATO WHERE NOT EXISTS (SELECT * FROM PERSONA_A_CARICO WHERE SSN = SSN_I) NOT EXISTS(I) restituisce TRUE se non vi sono tuple nel risultato dell interrogazione
17 Interrogazione 20 Si trovino i numeri di SSN di tutti i dipendenti che lavorano sui progetti 1, 2, o 3. SELECT DISTINCT SSN_I AS NUMERI_SSN_1_2_3 FROM LAVORA_SU WHERE N_P IN (1, 2, 3) Nella clausola WHERE è possibile usare insiemi espliciti di valori AS si può usare anche nella clausola SELECT per assegnare un alias ai nomi degli attributi 18 Tabelle collegate via JOIN Permette agli utenti di specificare una tabella risultante da un operazione di join (collegamento, unione) specificata nella clausola FROM di un interrogazione Questo costrutto può essere più facile da capire rispetto al mescolare insieme tutte le condizioni di selezione e di join nella clausola WHERE Condizione di JOIN > collegamento, associazione di tabelle Condizione di selezione > condizione sugli attributi
19 Interrogazione 21 (come la 1) Si trovino il nome e l indirizzo di tutti i dipendenti che lavorano per il dipartimento Ricerca. SELECT NOME_BATT, COGNOME, INDIRIZZO FROM (IMPIEGATO JOIN DIPARTIMENTO ON N_D = NUMERO_D) WHERE NOME_D = Ricerca ; La clausola FROM è su una singola tabella collegata via join: gli attributi di questa tabella sono tutti quelli di IMPIEGATO più tutti quelli di DIPARTIMENTO 20 Interrogazione 1 Si trovino il nome e l indirizzo di tutti i dipendenti che lavorano per il dipartimento Ricerca. SELECT NOME_BATT, COGNOME, INDIRIZZO FROM IMPIEGATO, DIPARTIMENTO WHERE NOME_D = Ricerca AND NUMERO_D = N_D; La seconda condizione è detta condizione di JOIN perché combina due tuple: una da DIPARTIMENTO e una da IMPIEGATO ogniqualvolta il valore di NUMERO_D in DIPARTIMENTO è uguale a N_D in IMPIEGATO.
21 Tipi di JOIN NATURAL JOIN INNER JOIN OUTER JOIN LEFT OUTER JOIN RIGHT OUTER JOIN 22 Interrogazione 22 - NATURAL JOIN Viene creata una condizione implicita di equijoin per ciascuna coppia di attributi con lo stesso nome. Ogni coppia di attributi di questo tipo è inclusa una sola volta nella relazione risultante SELECT NOME_BATT, CONGOME, INDIRIZZO FROM (IMPIEGATO NATURAL JOIN (DIPARTIMENTO AS DIP(NOME_D, N_D, MSSN, MSDATE))) WHERE NOME_D = Ricerca ; N_D è l attributo su cui si basa il NATURAL JOIN
23 Interrogazione 23 INNER JOIN Si mostri il nome del dipendente e del relativo supervisore. SELECT I.COGNOME AS NOME_IMPIEGATO, S.COGNOME AS NOME_SUPERVISORE FROM IMPIEGATO AS I JOIN IMPIEGATO AS S ON I.SUPER_SSN = S.SSN; È come SELECT I.COGNOME AS NOME_IMPIEGATO, S.COGNOME AS NOME_SUPERVISORE FROM IMPIEGATO AS I, IMPIEGATO AS S WHERE I.SUPER_SSN = S.SSN; È un join interno (INNER JOIN): una tupla è contenuta nel risultato solo se esiste una tupla corrispondente nell altra relazione. 24 Interrogazione 23 INNER JOIN
25 Interrogazione 24 LEFT OUTER JOIN Si mostri il nome del dipendente e del relativo supervisore. SELECT I.COGNOME AS NOME_IMPIEGATO, S.COGNOME AS NOME_SUPERVISORE FROM IMPIEGATO AS I LEFT OUTER JOIN IMPIEGATO AS S ON I.SUPER_SSN = S.SSN; LEFT OUTER JOIN: ogni tupla nella tabella di sinistra deve apparire nel risultato Se non esiste una tupla corrispondente, gli attributi della tabella di destra sono riempiti con valori NULL 26 Interrogazione 24 LEFT OUTER JOIN
27 Interrogazione 25 RIGHT OUTER JOIN Si mostri il nome del dipendente e del relativo supervisore. SELECT I.COGNOME AS NOME_IMPIEGATO, S.COGNOME AS NOME_SUPERVISORE FROM IMPIEGATO AS I RIGHT OUTER JOIN IMPIEGATO AS S ON I.SUPER_SSN = S.SSN; RIGHT OUTER JOIN: ogni tupla nella tabella di destra deve apparire nel risultato Se non esiste una tupla corrispondente, gli attributi della tabella di sinistra sono riempiti con valori NULL 28 Interrogazione 25 RIGHT OUTER JOIN
29 Funzioni di aggregazione Sono utilizzate per riepilogare in un unica tupla di sintesi le informazioni provenienti da tuple multiple Il raggruppamento e l aggregazione sono usati molto spesso COUNT SUM MIN MAX AVG 30 Interrogazione 26 Si calcoli la somma degli stipendi di tutti gli impiegati, lo stipendio massimo, quello minimo e quello medio SELECT SUM(STIPENDIO), MAX(STIPENDIO), MIN(STIPENDIO), AVG(STIPENDIO) FROM IMPIEGATO;
31 Interrogazione 27 Si calcoli la somma degli stipendi di tutti gli impiegati del dipartimento Ricerca e anche lo stipendio massimo, quello minimo e quello medio di questo dipartimento. SELECT SUM(STIPENDIO), MAX(STIPENDIO), MIN(STIPENDIO), AVG(STIPENDIO) FROM (IMPIEGATO JOIN DIPARTIMENTO ON N_D = NUMERO_D) WHERE NOME_D = Ricerca ; 32 Interrogazione 28 Si trovi il numero totale degli impiegati della società e il numero dei dipendenti del dipartimento Ricerca. SELECT COUNT(*) FROM IMPIEGATO; SELECT COUNT(*) FROM IMPIEGATO, DIPARTIMENTO WHERE N_D = NUMERO_D AND NOME_D = Ricerca ; L asterisco si riferisce alle righe
33 Interrogazione 29 Si calcoli il numero dei valori distinti degli stipendi presenti nella base di dati. SELECT COUNT(DISTINCT STIPENDIO) FROM IMPIEGATO; SELECT COUNT(DISTINCT STIPENDIO) FROM IMPIEGATO, DIPARTIMENTO WHERE N_D = NUMERO_D AND NOME_D = Ricerca ; 34 Funzioni di raggruppamento Sono utilizzate per creare sottogruppi di tuple in una tabella Individuano gruppi (che non si sovrappongono) costituiti dalle tuple che hanno lo stesso valore per uno o più attributi GROUP BY è la clausola utilizzata per specificare gli attributi di raggruppamento (devono essere presenti nella SELECT)
35 Interrogazione 30 Per ciascun dipartimento si trovino il numero del dipartimento, il numero degli impiegati del dipartimento e il loro stipendio medio. SELECT N_D, COUNT(*), AVG(STIPENDIO) FROM IMPIEGATO GROUP BY N_D; Le tuple di IMPIEGATO sono divise in gruppi, dove ciascun gruppo ha lo stesso valore di N_D Le funzioni COUNT e AVG sono applicate a ogni gruppo di tuple Se è presente un valore NULL, viene creato un gruppo separato 36 Interrogazione 30
37 Interrogazione 31 Per ciascun progetto si trovino il numero del progetto, il nome del progetto e il numero di impiegati che vi lavorano. SELECT NUMERO_P, NOME_P, COUNT(*) FROM PROGETTO, LAVORA_SU WHERE NUMERO_P = N_P GROUP BY NUMERO_P, NOME_P; 38 Interrogazione 31
39 Interrogazione 32 Per ciascun progetto in cui lavorano più di due impiegati si trovino il numero del progetto, il nome del progetto e il numero di impiegati che vi lavorano. SELECT NUMERO_P, NOME_P, COUNT(*) FROM PROGETTO, LAVORA_SU WHERE NUMERO_P = N_P GROUP BY NUMERO_P, NOME_P HAVING COUNT(*) > 2; HAVING fornisce una condizione sul gruppo di tuple associata al valore degli attributi di raggruppamento. 40 Interrogazione 32
41 Riepilogo delle interrogazioni SELECT <elenco attributi> FROM <elenco tabelle> [ WHERE <condizione> ] [ GROUP BY <condizione> ] [ HAVING <condizione> ] [ ORDER BY <elenco attributi> ]