Il Linguaggio SQL Le interrogazioni in SQL (continua…) • La parte di SQL dedicata alla formulazione di interrogazioni fa parte del DML. • SQL esprime le interrogazioni in modo dichiarativo, cioè specifica l’obbiettivo dell’interrogazione e non il modo come ottenerlo. • In tale caratteristica SQL si contrappone ai linguaggi ai linguaggi di interrogazione procedurali, come l’algebra relazionale. • Le istruzioni di interrogazione in SQL vengono specificate per mezzo dell’istruzione SELECT. Le interrogazioni SQL • La struttura essenziale di SELECT è: SELECT ListaAttributi FROM ListaTabelle [where condizione] • L’interrogazione SQL seleziona, tra le righe che appartengono al prodotto cartesiano delle tabelle elencate nella clausola “FROM”, quelle che soddisfano le condizioni espresse nell’argomento della clausola “WHERE”, le cui colonne si ottengono valutando le espressioni “ATTRESPR” contenute nella clausola SELECT. Come si può notare la clausola SELECT può avere come argomenti: • L’ * che rappresenta tutti gli attributi. • Espressioni. Interpretazione formale delle interrogazioni SQL • E’ possibile costruire una corrispondenza tra le interrogazioni SQL ed equivalenti interrogazioni in algebra relazionale. • Data una interrogazione SQL semplice: select T1.Attributo11, ….,Th.Attributohm from Tabella1 T1, ….., Tabellan Tn where Condizione • Diventa in algebra relazionale: πT1.Attributo11,….,Th.Attributoh(σCondizione (Tabella1 x…x Tabellan) • Naturalmente per interrogazioni SQL più complicate la formula sopra presentata non è direttamente applicabile. Se si usa l’operatore ALL vengono mantenute tutte le tuple. Una sintassi alternativa per la specifica del join (introdotta in SQL-2 e ancora in via di diffusione) permette di distinguere, tra le condizioni che compaiono nell’interrogazione, quelle che rappresentano condizioni di join e quelle che rappresentano condizioni di selezione sulle righe. In questo modo è possibile specificare le forme esterne dell’operatore di join. Inoltre, la condizione del join non compare come argomento della clausola where ma viene spostata nella clausola from. Il parametro TipoJoin specifica il tipo di join da usare: inner (che rappresenta il valore di default e quindi può essere omesso),right outer, left outer, full outer (il qualificatore outer è opzionale). L’ordinamento in base al primo attributo. Per righe che hanno lo stesso valore nel primo attributo si considerano i valori degli altri attributi in sequenza. Se il qualificatore (asc o desc) è omesso si usa l’ordinamento ascendente. Occorre notare che se le condizioni che i soottoinsiemi devono soddisfare sono verificabili al livello delle singole righe, allora basta usare dei predicati come argomento della clausola WHERE, altrimenti se le condizioni sono delle condizini di tipo aggregato occorre utilizzare un nuovo cotrutto: la clausola HAVING. SQL ammette l’utilizzo di predicati con un struttura più complessa di quanto visto finora. Una struttura in cui si confronta un valore (ottenuto come risultato di un’espressione valutato sulla singola riga) con il risultato di un’interrogazione SQL. La parola chiave ANY specifica che la riga soddisfa la condizione se risulta vero il confronto tra il valore dell’attributo per la riga e almeno uno degli elementi restituiti dalla sub-interrogazione. Altri esempi … • I dipartimenti in cui non lavorano persone di cognome “Rossi”: select Nome from Dipartimento where Nome <> all (select Dipart from Impegato where Cognome =“Rossi”) • Occorre sottolineare che il controllo di appartenenza o esclusione ad un insieme può essere effettuato in SQL con gli operatori IN e NOT IN, che risultano del tutto identici a = ANY e <> ALL. Interrogazioni nidificate: commenti • Un interpretazione semplice ed intuitiva delle interrogazioni nidificate consiste nell’assumere che l’interrogazione nidificata venga eseguita prima di analizzare le righe dell’interrogazione esterna. • Se però, l’interrogazione nidificata fa riferimento al contesto dell’interrogazione che la racchiude l’interpretazione semplice non può essere più applicata. Ciò accade quando una variabile, definita nell’ambito della query più esterna, è utilizzata nell’ambito della query più interna. • In quest’ultimo caso si parla di subquery correlate o anche di passaggio di binding. Esempio di subquery correlate • Data la seguente relazione: PERSONA(CodFiscale, Nome, Cognome, Città) • Trovare le persone che hanno degli omonimi(cioè stesso nome e cognome ma diverso codice fiscale): select * from Persona P where exists (select * from Persona P1 where P1.Nome = P.Nome and P1.Cognome = P.Cognome and P1CodFiscale <> P.CodFiscale ) • In tal caso sarebbe impossibile eseguire l’interrogazione interna prima di valutare l’interrogazione più esterna. Subquery correlate e scope • La semantica delle subquery correlate dice che l’interrogazione interna viene eseguita una volta per ciascuna ennupla dell’interrogazione esterna. • Per quanto riguarda la visibilità di una variabile SQL, vale la restrizione che una variabile è utilizzabile solo nella query in cui è definita o in una query nidificate (ad un qualsiasi livello) all’interno di essa. • Se un’interrogazione possiede interrogazioni nidificate allo stesso livello (ma su predicati distinti), le variabili introdotte dalla clausola FROM di una query nidificata non potranno essere usate dall’altra di pari livello. Uso di EXISTS • Data la seguente relazione: PERSONA(CodFiscale, Nome, Cognome, Città) • Trovare le persone che non hanno degli omonimi: select * from Persona P where not exists (select * from Persona P1 where P1.Nome = P.Nome and P1.Cognome = P.Cognome and P1CodFiscale <> P.CodFiscale ) • Con gli opertori EXISTS e NOT EXISTS si verifica se la query annidata restituisce almeno una tupla (exists) o nessuna tupla (not exists) La natura set-oriented di SQL presenta alcune particolarità di cui occorre tener conto quando si effettuano gli aggiornamenti. Le operazioni sopra indicate si riferiscono alla volontà di modificare gli stipendi dei dipendenti: aumentando del 10% quelli sotto i 30 mila e del 15% quelli sopra. Ad esempio usando il suddetto approccio si avrebbe per alcuni (ad esempio quelli che sono vicino alla soglia dei 30) un aumento complessivo del 26.5%.