Basi di Dati: Corso di laboratorio

Documenti analoghi
Il linguaggio SQL: query innestate

Data Management Software. Il linguaggio SQL. Query Innestate. Paolo Avallone Sr Consulting IT Specialist DB2, Data Management 10 Settembre 2003

Il linguaggio SQL: query innestate

Basi di Dati: Corso di laboratorio

Basi di Dati: Corso di laboratorio

Il linguaggio SQL: query innestate

Alessandra Raffaetà. Esercizio: Cinema

S.I.T. PER LA VALUTAZIONE E GESTIONE DEL TERRITORIO Corso di Laurea Magistrale in Scienze Ambientali. Alessandra Raffaetà

Basi di Dati: Corso di laboratorio

Operatori aggregati: COUNT

SELECT s.nome, e.data Studenti s, Esami e WHERE e.materia = 'BD' AND e.voto = 30 AND e.matricola = s.matricola

SQL - Sottointerrogazioni

Atzeni, Ceri, Paraboschi, Torlone Basi di dati McGraw-Hill, SQL

SQL - Sottointerrogazioni correlate

SQL quick reference. piccolo manuale di riferimento dei principali comandi SQL (prof. Claudio Maccherani, Perugia, 2013)

SQL - Structured Query Language

Interrogazioni nidificate

Interrogazioni nidificate

Structured Query Language

SQL: Structured Query Language. T. Catarci, M. Scannapieco, Corso di Basi di Dati, A.A. 2008/2009, Sapienza Università di Roma

Linguaggio SQL seconda parte

Structured. Language. Basi di Dati. Introduzione. DDL: Data Definition Language. Tipi di dato. Query. Modifica dei Dati

Database Lezione 2. Sommario. - Progettazione di un database - Join - Valore NULL - Operatori aggregati

Manuale SQL. Manuale SQL - 1 -

Interrogazioni in SQL

Linguaggio SQL. studenti matricola nome cognome citta anno 11 marco bini bologna laura sicuro rimini 1984 esami codice

Interrogare una base di dati: algebra relazionale e SQL. Savino Castagnozzi Giorgio Macauda Michele Meomartino Salvatore Picerno Massimiliano Sartor

Atzeni, Ceri, Paraboschi, Torlone Basi di dati McGraw-Hill, SQL

Elena Baralis 2007 Politecnico di Torino 1

SQL e algebra relazionale

σ data 15/12/2013 data 20/12/2014

Il linguaggio SQL: raggruppamenti

Tipi di sottoquery SQL

<Nome Tabella>.<attributo>

Corso di Basi di Dati A.A. 2015/2016

SQL [2] Concetti avanzati di SQL. Esempi di interrogazioni

ESERCIZI SQL. Esercizio 1

Le interrogazioni annidate

Basi di Dati: Corso di laboratorio

Esercitazione 3 SQL 2

Caratteristiche dei linguaggi per Database

Esempio di database relazionale con l utilizzo del prodotto MySQL

Basi di Dati. Esercitazione 1: Interrogazioni in SQL. K. Donno - Interrogazioni in SQL

PROGETTAZIONE DI DATABASE Linguaggio SQL

SQL Avanzato. Interrogazioni e il valore NULL. Interrogazioni complesse, trigger, viste e modifiche dello schema. Giorgio Giacinto 2015

Il linguaggio SQL: raggruppamenti. Versione elettronica: SQLb-gruppi.pdf

ESERCITAZIONI ACCESS

BASI DATI: algebra relazionale

Capitolo 4. SQL: il linguaggio di interrogazione. Originato da SEQUEL-XRM e System-R ( ) dell IBM

Basi di dati I 19 settembre 2016 Tempo a disposizione: un ora e 45 minuti.

Basi di Dati. Esercitazione SQL. Paolo Papotti. 19 maggio 2005

Query. Query (Interrogazioni) SQL SQL. Significato dell interrogazione. Sintassi

Basi di dati I Prova di autovalutazione 30 ottobre 2014

SQL (STRUCTURED QUERY LANGUAGE)

Eprogram ITIS V anno Unità 4 - Il linguaggio SQL

Il linguaggio SQL: viste e tabelle derivate. DB di riferimento per gli esempi

Basi di dati: appello 14/07/06

Data Base. Master "Bio Info" Reti e Basi di Dati Lezione 6

Microsoft Access (parte 5) Query. Query. Query. Query. Creare una query

Interrogare una base di dati: Algebra relazionale e SQL. Alessandro Bardine Alessandro Ciaramella Vincenzo Galella Rudy Manganelli

Esercitazione: Interrogazioni SQL

VARIABILI, ASSEGNAZIONE, DECISIONI

Business Intelligence

Interrogazioni complesse. SQL avanzato 1

Basi di dati 8 settembre 2015 Esame Compito A Tempo a disposizione: due ore. Libri chiusi.

Corso di Basi di Dati

Transcript:

Basi di Dati: Corso di laboratorio Lezioni 6 7 Raffaella Gentilini 1 / 46

Sommario 1 Subquery (o Interrogazioni Nidificate) Interrogazioni Annidate con Predicati di Confronto Interrogazioni Annidate con Predicati ALL, ANY Interrogazioni Annidate con Predicato EXISTS Subquery Correlate Livelli Multipli di Annidamento Subquery e Divisione 2 / 46

Subquery Subquery e uno statement in un altro statement si puo trovare nei seguenti punti dei seguenti statement: 1 nelle clausole WHERE e HAVING dello statement SELECT; 2 nella clausola WHERE di un INSERT INTO, DELETE FROM, UPDATE; 3 nella clausola SET di un comando UPDATE. dalla possibilita di annidare query deriva l aggettivo structured di SQL (Structured Query Language) 3 / 46

Subquery Subquery La forma nidificata e piu procedurale della forma flat, e per questo talvolta piu leggibile Una subquery e sempre tra parentesi e puo restituire: un singolo valore che si puo usare come espressione scalare una colonna che si puo usare come elenco di costanti una tabella che si puo usare ovunque e possibile usare una tabella Le subquery non possono contenere operatori insiemistici 4 / 46

Subquery Si consideri lo schema relazionale visto nelle lezioni precedente: persona(id persona, codice fiscale, nome, cognome, data nascita) corso(id corso, id insegnante, sigla, crediti, descrizione) frequenza(id studente,id corso,voto): dove id studente ed id corso sono chiavi esterne su persona e corso SELECT persona.nome, persona.cognome FROM persona WHERE persona.id persona IN (SELECT corso.id insegnante FROM corso) 5 / 46

Subquery Si consideri lo schema relazionale visto nelle lezioni precedente: persona(id persona, codice fiscale, nome, cognome, data nascita) corso(id corso, id insegnante, sigla, crediti, descrizione) frequenza(id studente,id corso,voto): dove id studente ed id corso sono chiavi esterne su persona e corso SELECT persona.nome, persona.cognome FROM persona WHERE persona.id persona IN (SELECT corso.id insegnante FROM corso) Nome e cognome degli insegnanti che tengono almeno un corso 6 / 46

Subquery e operatore IN Il predicato IN Il predicato puo essere applicato a liste di attributi puo essere negato SELECT persona.nome, persona.cognome FROM persona WHERE persona.id persona NOT IN (SELECT corso.id insegnante FROM corso WHERE corso.id insegnante IS NOT NULL) 7 / 46

Subquery e operatore IN Il predicato IN Il predicato puo essere applicato a liste di attributi puo essere negato SELECT persona.nome, persona.cognome FROM persona WHERE persona.id persona NOT IN (SELECT corso.id insegnante FROM corso WHERE corso.id insegnante IS NOT NULL) Nome e cognome degli insegnanti che non tengono alcun corso 8 / 46

Subquery e Predicati di Confronto Gli operatori di confronto =, <>, <, >, <=, >= si possono usare solo se l interrogazione annidata al piu una riga (subquery scalare) se la subquery non restituisce alcuna riga, il confronto da come risultato NULL in PostgreSQL, solo <> ed = sono supportati se il confronto coinvolge piu colonne SELECT id corso FROM corso WHERE crediti = (SELECT MAX(crediti) FROM corso ) 9 / 46

Subquery e Predicati di Confronto Gli operatori di confronto =, <>, <, >, <=, >= si possono usare solo se l interrogazione annidata al piu una riga (subquery scalare) se la subquery non restituisce alcuna riga, il confronto da come risultato NULL in PostgreSQL, solo <> ed = sono supportati se il confronto coinvolge piu colonne SELECT id corso FROM corso WHERE crediti = (SELECT MAX(crediti) FROM corso ) Id dei corsi con il massimo numero di crediti 10 / 46

Subquery e Predicati di Confronto Gli operatori di confronto =, <>, <, >, <=, >= si possono usare solo se l interrogazione annidata al piu una riga (subquery scalare) se la subquery non restituisce alcuna riga, il confronto da come risultato NULL in PostgreSQL, solo <> ed = sono supportati se il confronto coinvolge piu colonne SELECT id corso FROM corso WHERE crediti = (SELECT MAX(crediti) FROM corso ) Id dei corsi con il massimo numero di crediti 11 / 46

Subquery e Predicato ANY Per usare predicati di confronto con selezioni che possono restituire piu di una riga, occorre usare le quantificazioni ALL oppure ANY Il predicato ANY da vero se il confronto e vero per almeno una riga, da falso se tutti i confronti di riga sono falsi, o la subquery restituisce una tabella vuota se non ci sono confronti veri ed almeno uno e NULL, allora il risultato e NULL Il predicato IN e equivalente a = ANY 12 / 46

Subquery e Predicato ANY SELECT persona.nome, persona.cognome FROM persona WHERE persona.id persona = ANY (SELECT corso.id insegnante FROM corso) 13 / 46

Subquery e Predicato ANY SELECT persona.nome, persona.cognome FROM persona WHERE persona.id persona = ANY (SELECT corso.id insegnante FROM corso) Nome e cognome degli insegnanti che tengono almeno un corso 14 / 46

Subquery e Predicato ALL Il predicato ALL da vero se tutti i confronti di riga sono veri o la subquery restituisce la tabella vuota, da falso se almeno un confronto e falso restituisce NULL se non ci sono confronti falsi, ma almeno uno e indefinito Il predicato NOT IN e equivalente a <> ALL 15 / 46

Subquery e Predicato ALL SELECT persona.nome, persona.cognome FROM persona WHERE persona.id persona <> ALL (SELECT corso.id insegnante FROM corso WHERE corso.id insegnante IS NOT NULL) 16 / 46

Subquery e Predicato ALL SELECT persona.nome, persona.cognome FROM persona WHERE persona.id persona <> ALL (SELECT corso.id insegnante FROM corso WHERE corso.id insegnante IS NOT NULL) Nome e cognome degli insegnanti che non tengono alcun corso 17 / 46

Subquery e Predicato ALL SELECT persona.nome, persona.cognome FROM persona WHERE persona.id persona <> ALL (SELECT corso.id insegnante FROM corso WHERE corso.id insegnante IS NOT NULL) Nome e cognome degli insegnanti che non tengono alcun corso I valori NULL nella colonna id insegnante devono essere soppressi per evitare che rendano il predicato <> ALL non vero! 18 / 46

Subquery e Predicato EXISTS Il predicato EXISTS e vero se la subquery restituisce almeno una riga altrimenti e falso Facendo uso di NOT EXISTS e possibile verificare se la subquery non restituisce alcuna tupla SELECT persona.nome, persona.cognome FROM persona WHERE EXISTS (SELECT FROM corso WHERE crediti > 3) 19 / 46

Subquery e Predicato EXISTS Il predicato EXISTS e vero se la subquery restituisce almeno una riga altrimenti e falso Facendo uso di NOT EXISTS e possibile verificare se la subquery non restituisce alcuna tupla SELECT persona.nome, persona.cognome FROM persona WHERE EXISTS (SELECT FROM corso WHERE crediti > 3) Si noti che la query sopra non e molto interessante, in quanto il risultato della subquery e sempre lo stesso, ovvero non dipende dalla specifica tupla del blocco esterno 20 / 46

Subquery Correlate Se la subquery fa riferimento al blocco esterno, allora si dice correlata SELECT persona.nome, persona.cognome FROM persona P WHERE EXISTS (SELECT FROM corso C WHERE crediti > 3 AND id insegnante = P.id persona ) Adesso il risultato della query innestata dipende dalla persona specificata, e la semantica diventa: Per ogni tupla del blocco esterno, considera il valore di P.id persona e risolvi la query innestata 21 / 46

Subquery Correlate Se la subquery fa riferimento al blocco esterno, allora si dice correlata SELECT persona.nome, persona.cognome FROM persona P WHERE EXISTS (SELECT FROM corso C WHERE crediti > 3 AND id insegnante = P.id persona ) Insegnanti che tengono almeno un corso con piu di 3 crediti Adesso il risultato della query innestata dipende dalla persona specificata, e la semantica diventa: Per ogni tupla del blocco esterno, considera il valore di P.id persona e risolvi la query innestata 22 / 46

Subquery Correlate SELECT persona.nome, persona.cognome FROM persona WHERE EXISTS ( SELECT frequenza.voto FROM frequenza WHERE persona.id persona=frequenza.id studente AND frequenza.voto IS NOT NULL) AND 10 <= ALL ( SELECT frequenza.voto FROM frequenza WHERE persona.id persona=frequenza.id studente AND frequenza.voto IS NOT NULL) 23 / 46

Subquery Correlate SELECT persona.nome, persona.cognome FROM persona WHERE EXISTS ( SELECT frequenza.voto FROM frequenza WHERE persona.id persona=frequenza.id studente AND frequenza.voto IS NOT NULL) AND 10 <= ALL ( SELECT frequenza.voto FROM frequenza WHERE persona.id persona=frequenza.id studente AND frequenza.voto IS NOT NULL) Studenti che hanno preso solo voti superiori a 10 24 / 46

Livelli Multipli di Annidamento Una subquery puo fare uso a sua volta di altre subquery. Il risultato si puo ottenere risolvendo a partire dal blocco piu interno. persone(nome, eta, reddito) maternita (madre,figlio) paternita (padre,figlio) SELECT nome,reddito FROM persone WHERE nome IN. (SELECT padre FROM paternita. WHERE figlio =ANY. (SELECT nome FROM persone. WHERE reddito>40)) 25 / 46

Unnesting Unnesting E spesso possibile ricondursi ad una forma flat, ma la cosa non e sempre cosi ovvia. Ad esempio, la query precedente si puo anche scrivere come: SELECT DISTINCT p.nome,p.reddito FROM persone p, paternita, persone f WHERE p.nome=padre AND figlio=f.nome AND f.reddito>40 26 / 46

Subquery e Divisione Impiegati(CodiceImp, Nome, Sede, Ruolo, Stipendio) Sedi(Sede, Responsabile, Citta ) Le subquery permettono di eseguire la divisione relazionale. Sedi in cui sono presenti tutti i ruoli equivale a Quali sono le sedi che verificano: Per ogni ruolo, tale ruolo e presente nella sede? In SQL non esiste l operatore di quantificazione universale 27 / 46

Subquery e Divisione Impiegati(CodiceImp, Nome, Sede, Ruolo, Stipendio) Sedi(Sede, Responsabile, Citta ) Le subquery permettono di eseguire la divisione relazionale. Sedi in cui sono presenti tutti i ruoli equivale a Quali sono le sedi che verificano: Per ogni ruolo, tale ruolo e presente nella sede? Tuttavia xp(x) P(x). 28 / 46

Subquery e Divisione Impiegati(CodiceImp, Nome, Sede, Ruolo, Stipendio) Sedi(Sede, Responsabile, Citta ) Le subquery permettono di eseguire la divisione relazionale. Sedi in cui sono presenti tutti i ruoli equivale a Quali sono le sedi che verificano: Per ogni ruolo, tale ruolo e presente nella sede? Dunque possiamo scrivere in SQL una query equivalente a quelle sopra, riformulando il problema come: 29 / 46

Subquery e Divisione Impiegati(CodiceImp, Nome, Sede, Ruolo, Stipendio) Sedi(Sede, Responsabile, Citta ) Le subquery permettono di eseguire la divisione relazionale. Sedi in cui sono presenti tutti i ruoli equivale a Quali sono le sedi che verificano: Per ogni ruolo, tale ruolo e presente nella sede? Quali sono le sedi che verificano: Non esiste un ruolo non presente nella sede? 30 / 46

Subquery e Divisione Sedi in cui non esiste un ruolo sono non presente Mediante l uso di subquery, tale interrogazione si puo formulare in SQL come: SELECT Sede FROM Sedi AS S WHERE NOT EXISTS (SELECT FROM Impiegati I1 WHERE NOT EXISTS (SELECT FROM Impiegati I2 WHERE S.Sede=I2.Sede AND. I1.Ruolo=I2.Ruolo)) 31 / 46

Subquery e Divisione SELECT Sede FROM Sedi AS S WHERE NOT EXISTS (SELECT FROM Impiegati I1 WHERE NOT EXISTS (SELECT FROM Impiegati I2 WHERE S.Sede=I2.Sede AND. I1.Ruolo=I2.Ruolo)) Il blocco piu interno viene valutato per ogni combinazione di S ed I1 32 / 46

Subquery e Divisione SELECT Sede FROM Sedi AS S WHERE NOT EXISTS (SELECT FROM Impiegati I1 WHERE NOT EXISTS (SELECT FROM Impiegati I2 WHERE S.Sede=I2.Sede AND. I1.Ruolo=I2.Ruolo)) Il blocco intermedio funge da divisore (riguarda I1.Ruolo) 33 / 46

Subquery e Divisione SELECT Sede FROM Sedi AS S WHERE NOT EXISTS (SELECT FROM Impiegati I1 WHERE NOT EXISTS (SELECT FROM Impiegati I2 WHERE S.Sede=I2.Sede AND. I1.Ruolo=I2.Ruolo)) Data una sede S, se in S manca un ruolo: 34 / 46

Subquery e Divisione SELECT Sede FROM Sedi AS S WHERE NOT EXISTS (SELECT FROM Impiegati I1 WHERE NOT EXISTS (SELECT FROM Impiegati I2 WHERE S.Sede=I2.Sede AND. I1.Ruolo=I2.Ruolo)) Data una sede S, se in S manca un ruolo: la subquery piu interna non restituisce nulla 35 / 46

Subquery e Divisione SELECT Sede FROM Sedi AS S WHERE NOT EXISTS (SELECT FROM Impiegati I1 WHERE NOT EXISTS (SELECT FROM Impiegati I2 WHERE S.Sede=I2.Sede AND. I1.Ruolo=I2.Ruolo)) Data una sede S, se in S manca un ruolo: la subquery piu interna non restituisce nulla quindi la subquery intermedia restituisce almeno una tupla 36 / 46

Subquery e Divisione SELECT Sede FROM Sedi AS S WHERE NOT EXISTS (SELECT FROM Impiegati I1 WHERE NOT EXISTS (SELECT FROM Impiegati I2 WHERE S.Sede=I2.Sede AND. I1.Ruolo=I2.Ruolo)) Data una sede S, se in S manca un ruolo: la subquery piu interna non restituisce nulla quindi la subquery intermedia restituisce almeno una tupla... e la clausola WHERE non e soddisfatta per S 37 / 46

Subquery: come eseguire la divisione relazionale Vediamo un altro esempio: persona(id persona, codice fiscale, nome, cognome, data nascita) corso(id corso, id insegnante, sigla, crediti, descrizione) frequenza(id studente,id corso,voto) Chi sono gli studenti che seguono tutti i corsi di matematica? equivale a Chi sono gli studenti che verificano: Per ogni corso di matematica, lo studente segue tale corso?... e possiamo scrivere in SQL una query equivalente come: 38 / 46

Subquery: come eseguire la divisione relazionale Vediamo un altro esempio: persona(id persona, codice fiscale, nome, cognome, data nascita) corso(id corso, id insegnante, sigla, crediti, descrizione) frequenza(id studente,id corso,voto) Chi sono gli studenti che seguono tutti i corsi di matematica? equivale a Chi sono gli studenti che verificano: Per ogni corso di matematica, lo studente segue tale corso?... e possiamo scrivere in SQL una query equivalente come: Chi sono gli studenti che verificano: Non esiste un corso di matematica non seguito dallo studente 39 / 46

Subquery: come eseguire la divisione relazionale (II) Mediante l uso di subquery, tale interrogazione si puo formulare in SQL come: SELECT DISTINCT nome,cognome FROM persona AS p WHERE NOT EXISTS ( SELECT FROM ( SELECT FROM corso WHERE sigla LIKE mat% ) AS c WHERE NOT EXISTS ( SELECT FROM persona JOIN frequenza ON id persona=id studente WHERE id persona=p.id persona AND id corso=c.corso)) 40 / 46

SQL e Divisione Un altra possibilita di riformulare il problema per tradurlo in SQL e data da: Chi sono gli studenti che verificano: Il numero di corsi di matematica seguiti dallo studente equivale al numero totale dei corsi di matematica. 41 / 46

SQL e Divisione Chi sono gli studenti che verificano: Il numero di corsi di matematica seguiti dallo studente equivale al numero totale dei corsi di matematica. SELECT id persona, nome, cognome FROM persona JOIN frequenza ON id persona=id studente JOIN corso USING (id corso) WHERE corso.sigla LIKE mat% GROUP BY id persona,nome,cognome HAVING COUNT ( DISTINCT corso.id corso) = (SELECT COUNT( ) FROM corso WHERE sigla LIKE mat% ); 42 / 46

SQL e Divisione Chi sono gli studenti che verificano: Il numero di corsi di matematica seguiti dallo studente equivale al numero totale dei corsi di matematica.... oppure... SELECT id persona, nome, cognome FROM persona WHERE ( SELECT COUNT ( DISTINCT id corso) FROM frequenza NATURAL JOIN corso WHERE sigla LIKE mat% AND id studente=id persona) = (SELECT COUNT( ) FROM corso WHERE sigla LIKE mat% ); 43 / 46

Subquery: Aggiornamento dei Dati Le subquery si possono efficacemente usare per aggiornare i dati di una tabella sulla base di criteri che dipendono dal contenuto di altre tabelle DELETE FROM persona WHERE persona.id persona NOT IN (SELECT corso.id insegnante FROM corso WHERE corso.id insegnante IS NOT NULL) 44 / 46

Subquery: Aggiornamento dei Dati Le subquery si possono efficacemente usare per aggiornare i dati di una tabella sulla base di criteri che dipendono dal contenuto di altre tabelle DELETE FROM persona WHERE persona.id persona NOT IN (SELECT corso.id insegnante FROM corso WHERE corso.id insegnante IS NOT NULL) Elimina gli insegnanti che non tengono alcun corso 45 / 46

Subquerye CHECK Lo standard SQL prevede l utilizzo del delle interrogazioni annidate anche nella clausola CHECK Nota: Questa caratteristica non e supportata attualmente da PostgreSQL (per far fronte a cio si usano i trigger, cfr. Lezione 9).... nella creazione della tabella ImpiegatiPG, degli impiegati di Perugia CHECK ( NOT EXISTS (SELECT FROM ImpiegatiUD WHERE ImpiegatiUD.codiceImp=ImpiegatiUD.codicePG)) 46 / 46