Appunti del Prof. Di Capua Giuseppe BASI DI DATI & SQL Appunti del Prof. Di Capua Giuseppe INDICE 1 CENNI SULLA PROGETTAZIONE.................................................................................3 1.1 2 I DATABASE RELAZIONALI ...............................................................................................4 IL LINGUAGGIO SQL ........................................................................................................7 2.1 ATTIVARE SQL DA ACCESS ..............................................................................................7 2.2 ALCUNE NOTIZIE ..............................................................................................................8 2.3 LE ISTRUZIONI DEL DDL ..................................................................................................9 2.3.1 Creazione di una tabella .........................................................................................9 2.3.2 Creazione di un indice...........................................................................................12 2.3.3 Modifica di una tabella .........................................................................................13 2.3.4 Eliminare una tabella ............................................................................................13 2.3.5 Eliminare un indice ...............................................................................................14 2.4 LE ISTRUZIONI DEL DML................................................................................................15 2.4.1 Inserire dati in una tabella: Il comando INSERT .................................................16 2.4.2 Modificare i dati in una tabella: Il comando UPDATE ........................................17 2.4.3 Cancellare i dati in una tabella: Il comando DELETE.........................................18 2.4.4 Selezionare i dati : Il comando SELECT...............................................................18 2.4.4.1 Lettura esaustiva ................................................................................................18 2.4.4.2 Lettura di colonne (operazione di Proiezione) ..................................................19 2.4.4.3 Selezionare righe (operazione di restrizione) ....................................................20 2.4.4.4 Ordinamenti .......................................................................................................24 2.4.4.5 Funzioni di gruppo ............................................................................................25 2.4.4.6 Raggruppamenti ................................................................................................28 2.4.4.7 Le operazioni di Join (prodotto cartesiano).......................................................29 2.4.4.8 Le Subquery.......................................................................................................32 2 Appunti del Prof. Di Capua Giuseppe 1 Cenni sulla progettazione Com’è noto, un data base può essere inteso come una raccolta di dati organizzati e ben strutturati, coordinata da un sistema software generalizzato che ne renda facilmente gestibile il reperimento di informazioni da parte di più utenti. Uno dei compiti del software generalizzato di gestione del data base consiste nel memorizzare i dati in modo da rendere possibili le seguenti operazioni: • aggiornamento del data base attraverso l’inserimento di nuovi dati • modifica del data base • recupero dei dati attraverso ricerche • cancellazione di dati Il software che consente di gestire un database è detto DBMS (DataBase Management System). Il DBMS permette agli utenti di gestire una macchina astratta che rende possibile la gestione del database. Questa macchina virtuale può essere schematizzata in livelli: Livello Esterno Sottoschema Sottoschema Livello Logico Schema Logico Livello Fisico Schema Fisico Il Livello Esterno è il livello che consente agli utenti di gestire i dati attraverso dei programmi applicativi. Un sottoschema o vista rappresenta i dati a cui un utente può accedere. Infatti, non tutti gli utenti possono essere interessati all’intero data base o possono gestire tutti i dati. Per questo motivo, si creano delle viste logiche, contenenti cioè solo i dati che un utente può gestire. I programmi o le viste sono indipendenti dall’organizzazione logica dei dati (indipendenza logica), nel senso che se viene modificato lo schema logico non occorre modificare tutti i programmi o le viste ma solo quelle direttamente interessate alla modifica dello schema logico. Il DBMS mette a disposizione un linguaggio detto DML (Data Manipulation Language) che consente di gestire i dati (Inserimento, cancellazioni, modifiche e interrogazione dei dati) 3 Appunti del Prof. Di Capua Giuseppe Il Livello Logico o Concettuale è il livello in cui si trova la rappresentazione astratta del database. Astratta perché tale rappresentazione è indipendente dal livello fisico (Indipendenza fisica). Per descrivere le caratteristiche dello schema logico, occorre adottare un linguaggio detto DDL (Data Definition Language), offerto dal DBMS. Il Livello Fisico gestisce il database fisico, ovvero come le informazioni sono memorizzate sulle memorie di massa. Questo livello si interfaccia con la parte del Sistema Operativo che gestisce i file (File System). A questo proposito, Il DBMS offre un ulteriore linguaggio detto DMCL (Data Media Control Language) che consente di organizzare i dati a livello fisico . Perciò, per progettare un database occorre prevedere 3 fasi di lavoro: • • • Progettazione Concettuale Progettazione Logica Progettazione Fisica La Progettazione Concettuale ha lo scopo di definire e schematizzare la realtà che si vuole rappresentare indipendentemente dal DBMS che si utilizzerà. Questa progettazione genera uno schema concettuale, realizzabile attraverso il Diagramma E/R (Entità/Relazione), in cui gli elementi di interesse della realtà vengono rappresentati attraverso delle Entità. Le entità sono caratterizzate da Attributi e sono collegate tra loro attraverso Associazioni o Relazioni. La Progettazione Logica ha lo scopo di trasformare lo schema concettuale in uno schema logico attraverso, per esempio, la definizione di tabelle e relazioni tra esse (Database Relazionale) La Progettazione Fisica ha lo scopo di implementare lo schema logico, attraverso la definizione di aspetti riguardanti la memorizzazione dei dati su memorie di massa. 1.1 I Database Relazionali In un database Relazionale i dati sono organizzati in un sistema di tabelle contenenti dati logicamente correlati fra loro attraverso delle relazioni tra l'una e l'altra tabella. Ogni tabella è costituita da colonne (campi) e ogni colonna ha una specifica caratteristica (dominio). Le righe della tabella sono dette record o tuple. E’ possibile che all’interno di una tupla ci sia uno o più campi che identificano in maniera univoca un record rispetto a tutti gli altri record. In questo caso quel campo viene indicato con il termine di chiave primaria. Ci possono essere, inoltre, dei campi che servono a relazionare (collegare) una tabella con un’altra tabella . Tali campi identificano la cosiddetta chiave esterna. La cosa importante è che i campi in relazione devono appartenere allo stesso dominio. Esempio: Si prenda in esame un database che si pone come obiettivo la gestione dei voti degli alunni di una classe. Si vogliano registrare i risultati di tutte le prove (scritte e orali) di tutti gli alunni in tutte le materie. Le informazioni che occorre memorizzare sono: 4 Appunti del Prof. Di Capua Giuseppe • • • • • • I dati dell’alunno La materia In nome del docente La data della prova Il voto il tipo di prova (scritta/orale) Nel modo "classico" avremmo realizzato un' unica tabella più o meno di questo tipo: Cognome Nome Materia Docente Data Bianchi Viola Bianchi Rossi Celeste Rossi Nero Andrea Lucia Andrea Daniele Antonio Daniele Katia Italiano Matematica Fisica Italiano Geografia Matematica Italiano Buffon Angela Toldo Luigi Abbiati Luca Buffon Angela Peruzzi Franco Toldo Luigi Buffon Angela 12/10/2005 12/10/2005 13/10/2005 13/10/2005 15/10/2005 20/10/2005 20/10/2005 Voto Tipo di Prova 7 Orale 5,5 Orale 4 Orale 6 Orale 4,5 Orale 6 Orale 5 Orale Appare evidente, in questo modo, come sussista il problema della ridondanza dei dati (abbiamo registrato l’alunno Bianchi Andrea 2 volte, il docente Buffon Angela 3 volte), il che può provocare - a lungo andare - anche il fenomeno negativo dell’inconsistenza dei dati stessi. Il modello relazionale consente di dividere una tabella in più tabelle senza, ovviamente, causare perdita di alcuna informazione, ma facendo in modo da eliminare, per esempio, la ridondanza dei dati. Ritornando all’esempio ipotizzato, si possono allora creare 4 tabelle : • • • • Una prima tabella (Alunni) memorizzerà i dati degli alunni della classe con tutti i dati di interesse di un alunno. Una seconda tabella (Materie) con i dati delle materie e dei docenti che l’insegnano. Una terza (Tipologia) con i tipi di prove Una quarta tabella (Prove) conterrà i dati relativi alle prove sostenute dagli studenti. Tabella Alunni CodAlunno* 1 2 3 4 5 5 Cognome Bianchi Celeste Nero Rossi Viola Nome Andrea Antonio Katia Daniele Lucia Data di Nascita 09/07/1990 02/06/1990 12/03/1990 19/10/1990 15/12/1990 Luogo di Nascita Avellino Avellino Avellino Avellino Avellino Appunti del Prof. Di Capua Giuseppe Tabella Materia CodMateria * 1 2 3 4 Materia Italiano Matematica Fisica Geografia Docente Buffon Angela Toldo Luigi Abbiati Luca Peruzzi Franco Tabella Tipologie CodTipo * 1 2 3 Descrizione Orale Scritto Pratica Tabelle Prove Prog.* 1 2 3 4 5 6 7 CodAlunno 1 5 1 4 2 4 3 CodMateria 1 2 3 1 4 2 1 Data Prova 12/10/2005 12/10/2005 13/10/2005 13/10/2005 15/10/2005 20/10/2005 20/10/2005 Voto 7 5,5 4 6 4,5 6 5 CodTipo 1 1 1 1 1 1 1 Questa soluzione consentirà di ridurre o addirittura di eliminare le ripetizioni degli stessi dati in più righe di tabelle: inseriremo una sola volta Bianchi Andrea per tutte le volte che vorremo usarlo in punti differenti del nostro database ed avremo sempre la certezza di chiamarlo correttamente e non Bianci Andrea o Andrea Bianchi ecc.. I campi con * sono chiavi primarie mentre gli altri codici della tabella Prove sono chiavi esterne e sono relazionate (vedi i colori) con i campi chiave delle altre tabelle. Poniamoci ora una domanda: leggendo dalla tabella Prove, come facciamo a capire che la l’alunno Rossi è stato interrogato in Italiano ? La risposta ci è fornita dalle relazioni. Ogni tabella, infatti possiede un codice univoco (la chiave primaria ) che identifica solo ed esclusivamente una riga (non ci sono né possono essere due alunni con CodAlunno = 1). Notiamo che tali codici vengono richiamati all' interno della tabella delle Prove: si può quindi dire si è stabilita una relazione tra il campo CodAlunno della tabella Prove (Chiave esterne) e il campo CodAlunno della tabella Alunni. Allo stesso modo si ha una relazione tra CodMateria della tabella Materie e CodMateria della tabella Prove. In questo capitolo non ci occuperemo in dettaglio di progettazione, bensì delle modalità di gestione dei diversi livelli di un database attraverso l’uso di un linguaggio denominato SQL. 6 Appunti del Prof. Di Capua Giuseppe 2 Il linguaggio SQL Il linguaggio SQL (Structured Query Language) è diffuso su tutti i DBMS che usano il modello relazionale dei dati; esso consente di definire relazioni e di esprimere interrogazioni e modifiche a una base di dati. L’SQL è un linguaggio dichiarativo e non procedurale. Le istruzioni dell’SQL si possono classificare in: DDL (Data Definition Language) contiene le istruzioni per la gestione dello schema logico, ovvero consente di create tabelle, creare indici ecc.. DML (Data Manipulation Language) contiene le istruzioni per la gestione dei dati contenuti nelle tabelle, ovvero consente di inserire , cancellare, modificare e ricercare dati . DCL (Data Control Language) contiene le istruzioni per la gestione delle operazioni, ovvero consente di definire per gli utenti i permessi sulle tabelle (quali operazioni possono fare sulle tabelle), di definire i permessi di accesso ai dati, ecc… 2.1 Attivare SQL da Access Per attivare i comandi di SQL da Access, occorre seguire la procedura per creare una query (vedi paragrafi precedenti). Senza dover necessariamente selezionare una tabella si procede dalla barra del menu con Visualizza Visualizzazione SQL Apparirà una finestra del tipo : nella quale possono essere scritte le istruzioni SQL. Per poter eseguire le istruzioni scritte occorre selezionare il bottone presente sulla barra. Una volta eseguita la query per ritornarci sopra occorre selezionare : Visualizza Visualizzazione SQL 7 Appunti del Prof. Di Capua Giuseppe 2.2 Alcune notizie SQL è un linguaggio case unsensitive quindi tutte le istruzioni possono essere scritte sia in maiuscolo che in minuscolo. I nomi delle tabelle e dei campi possono avere come carattere speciale solo “_” (underscore). Non utilizzare come separatore il carattere “.” (punto) perché il punto è usato per riferirsi al campo di una tabella secondo la notazione: Nometabella.nomecampo Alcuni dei tipi di dati che si possono utilizzare sono tipicamente quelli riportati sotto in tabella. Nome Tipo Charter(N) o Carattere Char(N) Integer o Int Smallint Decimal(P,D) o Dec(P,D) Float Real Date Time Intero Intero Decimale Decimale Decimal Data Ora Descrizione Definisce una colonna atta a contenere una stringa di caratteri alfanumerici di lunghezza fissa N. La lunghezza è opzionale. Se non fornita, si assume uguale a 1 Numero intero Numero intero Numero Reale con P cifre prima della virgola e D cifre decimali Numero Reale Floating point (virgola mobile) Numero Reale Floating point (virgola mobile) Formato aa/mm/gg Formato hh:mm Per le costanti di tipo stringa si usano i separatori ‘ oppure “. Nelle espressioni si possono usare i seguenti operatori: matematici +, -, *, / relazionali <, >, <=, >=, <> logici and, or, not Nella sintassi successiva indicheremo in grassetto le parole chiavi del linguaggio SQL e le opzioni non obbligatorie saranno racchiuse tra parentesi quadre []. 8 Appunti del Prof. Di Capua Giuseppe 2.3 Le istruzioni del DDL 2.3.1 Creazione di una tabella Il comando per la creazione di una tabella è Create Table . La sintassi di questo comando è molto articolata. Di seguito ne presentiamo una versione semplificata adatta ai nostri scopi: CREATE TABLE NomeTabella( NomeColonna1 Dominio [NOT NULL[UNIQUE]] [,NomeColonna2 Dominio [NOT NULL[UNIQUE]]... [, PRIMARY KEY (ListaDiNomiDiColonna)] ) dove: f NomeTabella è il nome della relazione che viene creata; f NomeColonna Dominio [,NomeColonna Dominio]... e’ l’elenco separato da virgole degli attributi (con relativo dominio) che fanno parte della relazione, ovvero l’elenco dei campi della tabella. Ricordiamo che ogni tabella deve avere almeno un campo; f NOT NULL è opzionale ed indica che il campo è obbligatorio e perciò non può contenere valori nulli. f UNIQUE è opzionale ed indica che il campo non potrà contenere valori duplicati. f PRIMARY KEY è opzionale e specifica quali attributi fanno parte della chiave primaria. La successiva ListaDiNomiDiColonna (facente sempre parte dell’opzione PRIMARY KEY) è una lista separata da virgole di nomi di campi (attributi). Esempio 1: Si voglia creare una tabella Anagrafica Impiegati, con tuple ciascuna costituita da 6 campi (attributi): Attributo Codice Identificativo Nome Impiegato Mansione Data Assunzione Stipendio Premio Numero Dipartimento Tipo Numero intero Alfanumerico Alfanumerico Data Numero con decimali Numero con decimali Numero intero Il codice SQL per creare la tabella Impiegati è: CREATE TABLE Impiegati( ImpId Integer not null, Nome Char(20) not null, Mansione Char(10) not null, Data_ass Date not null, Stipendio Real, Premio_P Real, DipNum integer not null PRIMARY KEY (ImpId) 9 Lunghezza 4 cifre 20 caratteri 10 caratteri Predefinita 3 cifre Appunti del Prof. Di Capua Giuseppe ); Esempio 2: Si voglia creare una tabella Dipartimenti, con record costituiti da 5 campi (attributi): Attributo Numero Dipartimento Nome Dipartimento Sigla Ufficio Codice Divisione Identificativo Dirigente Tipo Numero intero Alfanumerico Alfanumerico Alfanumerico Numero intero Lunghezza 3 cifre 20 caratteri 5 caratteri 2 caratteri 4 cifre CREATE TABLE Dipartimenti( DipNum Integer not null, NomeDip Char(20) not null, Ufficio Char(5) not null, Divisione Char(2) not null, Dirigente integer not null, PRIMARY KEY (DipNum) ); Esempio3 : Si voglia creare una tabella Anagrafica Docenti, con record costituiti da 3 campi: Attributo Identificativo Docente Cognome Nome Tipo Numero intero Alfanumerico Alfanumerico Lunghezza 3 cifre 20 caratteri 20 caratteri CREATE TABLE Docenti( Iddocente integer not null, Cognome Char(20) not null, Nome Char(20) not null, PRIMARY KEY (Iddocente) ); Esempio 4: Si voglia creare una tabella Anagrafica Corsi, con record costituiti da 3 campi: Attributo Codice Corso Descrizione Identificativo Docente Tipo Alfanumerico Alfanumerico Numero intero CREATE TABLE Corsi( Codcorso Char(3) not null, Descrizione Char(20) not null, Iddocente integer not null, PRIMARY KEY (Codcorso) ); 10 Lunghezza 3 caratteri 20 caratteri 3 cifre Appunti del Prof. Di Capua Giuseppe Esempio 5: Si voglia creare una tabella Anagrafica Studenti, con record costituiti da 2 campi: Attributo Matricola Cognome Tipo Numero intero Alfanumerico Lunghezza 4 cifre 20 caratteri CREATE TABLE Studenti( Matricola integer not null, Cognome Char(20) not null, PRIMARY KEY (Matricola) ); Esempio 6: Si voglia creare una tabella Esami, con record costituiti da 3 campi (attributi): Attributo Matricola Corso Voto Tipo Numero intero Alfanumerico Numero intero Lunghezza 4 cifre 3 caratteri 2 cifre CREATE TABLE Esami( Matricola integer not ull, corso Char(3) not null, voto integer not null, PRIMARY KEY (Matricola,corso) ); Attraverso Access, una volta attivata la finestra SQL e scritta una delle sintassi sopra riportate, si seleziona il tasto . A questo punto chiudendo SQL e andando nella finestra database alla voce Tabelle ci sarà la tabella creata. All’interno di una creazione di tabella è possibile inserire altri istruzioni. Le principali istruzioni sono: FOREIGN KEY (ListaDiNomiDiColonna1) REFERENCES Nometabella (ListaDiNomiDiColonna2), dove ListaDiNomiDiColonna1 sono le colonne che fanno parte di una chiave esterna che sono referenziate (ovvero corrispondono) alle (ListaDiNomiDiColonna2) della tabella Nometabella. In questo modo si stabilisce un’integrità referenziale tra le due tabelle. Esempio 4: Integrità Referenziale – Relazione tra le tabelle Impiegati e Dipartimenti attraverso i campi DipNum presenti in ambedue le tabelle. CREATE TABLE Impiegati( ImpId Integer not null, Nome Char(20) not null, 11 Appunti del Prof. Di Capua Giuseppe Mansione Char(10) not null, Data_ass Date not null, Stipendio Real, Premio_P Real, DipNum Integer, PRIMARY KEY (ImpId), FOREIGN KEY (DipNum) REFERENCES Dipartimenti(DipNum) ); Esempio 5: Integrità Referenziale – Relazione tra le tabelle Corsi e Docenti attraverso i campi IdDocenti presenti in ambedue le tabelle. CREATE TABLE Corsi( Codcorso Char(3) not null, Descrizione Char(20) not null, Iddocente integer not null, PRIMARY KEY (Codcorso), FOREIGN KEY (Iddocente) REFERENCES Docenti(Iddocente) ); 2.3.2 Creazione di un indice E’ possibile associare ad una tabella un indice. Un indice contiene uno o più campi della tabella ed ha lo scopo di semplificare e velocizzare le ricerche sulla tabella. Quando si crea un indice in effetti viene creata una nuova tabella contenente solo i campi di indice. Il linguaggio SQL si serve di tale indice quando effettua ricerche o aggiornamenti: nell’indice, infatti i dati sono ordinati rispetto all’attributo relativo e quindi più facilmente rintracciabili. Per creare un indice la sintassi è: CREATE [UNIQUE] INDEX nomeindice ON nometabella (nomecolonna1,nomecolonna2,…,nomecolonnaN) dove: f UNIQUE indica che l’indice è univoco ovvero non ammette duplicati. Se tale clausola non è indicata i campi dell’indice ammettono dati duplicati. f nomeindice è il nome da dare all’indice. f nometabella è il nome della tabella. f nomecolonna1, nomecolonna2,…. sono delle colonne che fanno parte dell’indice. Esempio 1: Creazione Indice nella Tabella Impiegati– l’indice si baserà sui campi Mansione ed a parità sulla Data Assunzione del dipendente. CREATE INDEX indice1 ON Impiegati(Mansione, Data_ass) 12 Appunti del Prof. Di Capua Giuseppe 2.3.3 Modifica di una tabella Il comando per la modifica della struttura di una tabella è Alter Table. La sintassi di questo comando è ALTER TABLE NomeTabella ADD nomecolonna tipo MODIFY nomecolonna nuovotipo DROP COLUMN nomecolonna dove: f ADD consente di aggiungere una nuova colonna indicata in nomecolonna di tipologia indicata da tipo. f MODIFY consente di modificare la tipologia di una colonna indicata da nomecolonna in una tipologia indicata da tipo. f DROP COLUMN consente di eliminare la colonna indicata in nomecolonna. Esempio 1: Modifica tabella ALTER TABLE Studenti ADD Nome char(20) Effetto: viene aggiunta la colonna Nome che conterrà una stringa di 20 Esempio 2: Modifica tabella ALTER TABLE Impiegati MODIFY Nome char(25) Effetto: la colonna Nome passa da una stringa di 20 a una stringa di 25. 2.3.4 Eliminare una tabella Quando si elimina una tabella occorre prestare molta attenzione, in quanto ciò può provocare il fenomeno dell’inconsistenza. Infatti, se le tabelle sono collegate attraverso chiavi esterne la cancellazione di una di queste tabella provocherà la violazione di integrità. Per eliminare una tabella il comando è DROP TABLE nometabella [RESTRICT|CASCADE|SET NULL] dove : f RESTRICT non consente la cancellazione della tabella se è collegata ad altre tabelle. f CASCADE cancella la tabella e tutte le tabelle ad essa collegate. f SET NULL cancella la tabella e mette nelle chiavi esterne delle tabelle collegate il valore null. 13 Appunti del Prof. Di Capua Giuseppe Esempio 1: Elimina la tabella Studenti DROP TABLE Studenti 2.3.5 Eliminare un indice Oltre alla tabella è possibile eliminare anche indici creati precedentemente . Per eliminare un indice il comando è DROP nomeindice Esempio 1: Elimina l’indice 1: DROP indice1 14 Appunti del Prof. Di Capua Giuseppe 2.4 Le istruzioni del DML Prima di analizzare le istruzioni del DML ipotizziamo che, dopo aver provveduto alla loro creazione (attraverso i comandi CREATE TABLE visti in precedenza) si debba procedere all’immissione dei dati seguenti: Tabella Impiegati ImpId 7369 7499 7521 7566 7654 7698 7782 7788 7839 7844 7876 7900 7902 7934 7977 Nome Rossi Andre Bianchi Rosi Martini Blacchi Neri Scotti Dare Turni Adami Gianni Fordi Milli Verdi Mansione ingegnere tecnico tecnico dirigente segretario dirigente ingegnere segretaria ingegnere tecnico ingegnere Ingegnere Segretario Ingegnere Dirigente Data_Ass 17-Dic-80 20-Feb-81 20-Feb-8 02-Apr-81 28-Set-81 01-Mag-81 01-Giu-81 09-Nov-81 17-Nov-81 08-Set-81 28-Set-81 03-Dic-81 03-Dic-81 23-Gen-82 10-Dic-80 Stipendio 1600,00 800,00 800,00 2975,00 800,00 2850,00 2450,00 800,00 2600,00 1500,00 1100,00 1950,00 1000,00 1300,00 3000,00 Divisione D1 D1 D2 Dirigente 7977 7566 7698 Tabella Dipartimenti DipId 10 20 30 NomeDip Edilizia Civile Ricerche Edilizia Stradale Ufficio 1100 2200 5100 Tabella Studenti Matricola 2456 3456 3566 5434 7837 15 Cognome Rossi Azzurro Giallo Rossi Verdi Nome Giovanni Giulia Antonio Ugo Alfredo PremioP 500,00 100,00 200,00 300,00 500,00 150,00 DipNum 20 30 30 20 30 30 10 20 10 30 20 30 20 10 10 Appunti del Prof. Di Capua Giuseppe Tabella Docenti Codcorso 10 20 30 Cognome Zarro Perna Granese Nome Antonio Luca Luigia Tabella Corsi Codcorso A01 A02 A03 A04 A05 Descrizione Analisi I Fisica Chimica Analisi II Biologia Docente 10 20 20 10 30 Tabella Esami Matricola 5434 7837 5434 3566 5434 3566 Corso A01 A01 A02 A03 A03 A01 Voto 25 29 30 28 24 23 2.4.1 Inserire dati in una tabella: Il comando INSERT Il comando INSERT consente di inserire nuove righe all’interno di una tabella. La sintassi è INSERT INTO Nometabella [nomecolonna1,nomecolonna2,…nomecolonnaN] VALUES (valore1,valore2,…..,valoreN) Dove : f Nometabella è il nome della tabella in cui inserire i dati; f nomecolonna1,nomecolonna2,…nomecolonnaN sono i nomi delle colonne in cui inserire i dati. Tali nomi sono opzionali f valore1,valore2,…..,valoreN sono i valori da inserire nelle colonne. Tali valori verranno inseriti in maniera posizionale rispetto al nome delle colonne indicate Se i nomi delle colonne non vengono indicate, i valori verranno inseriti in maniera posizionale rispetto alle colonne come definite nella tabella. Se non si inseriscono dei valori si considera il valore null 16 Appunti del Prof. Di Capua Giuseppe Esempio 1: Inserimento di un record . INSERT INTO Studenti VALUES (‘4675’,’Rossi’,’Adelaide’) 2.4.2 Modificare i dati in una tabella: Il comando UPDATE Il comando UPDATE consente di modificare i dati inseriti all’interno di una tabella. La sintassi è: UPDATE Nometabella SET nomecolonna1=valore1, nomecolonna2=valore2, ……………………… nomecolonnaN=valoreN [WHERE condizione] dove f Nometabella è il nome della tabella in cui modificare i dati; f nomecolonna1=valore1 …..indica che in nomecolonna1 verrà inserito valore1. Occorre sottolineare che valore1 può essere anche un’espressione aritmetica ; f WHERE condizione indica quali righe sono soggette alla variazione. Se tale clausola non viene indicata verranno aggiornate tutte le righe della tabella. Esempio 1: Modifica il record della tabella Dipartimenti che presenta l’identificazione del dipendente 20. UPDATE Dipartimenti SET Divisione = ‘D2’ Where dipid = 20 In questo modo solo il record che ha nel campo dipId il valore 20 verrà aggiornato. Senza la clausola Where avremmo avuto l’aggiornamento di tutti i record della tabella. 17 Appunti del Prof. Di Capua Giuseppe 2.4.3 Cancellare i dati in una tabella: Il comando DELETE Il comando DELETE consente di cancellare i dati inseriti all’interno di una tabella. La sintassi è DELETE FROM Nometabella [WHERE condizione] dove: f Nometabella è il nome della tabella in cui cancellare i dati; f WHERE condizione indica quali righe saranno cancellate. Se tale clausola non viene indicata verranno cancellate tutte le righe della tabella. Esempio 1: Cancellare il record dalla Tabella Studenti relativo ad una data matricola DELETE FROM Studenti Where Matricola = ‘3456’ verrà cancellato il record con matricola = 3456 (corrispondente a Azzurro Giulia dell’esempio sopra riportato). 2.4.4 Selezionare i dati : Il comando SELECT Il verbo SELECT può essere utilizzato ogni volta che si vuole accedere al database in lettura, allo scopo di eseguire interrogazioni sui dati memorizzati. Il risultato di questa istruzione è una tabella che contiene i dati selezionati dal database. La sintassi generica del comando è: SELECT [ALL|DISTINCT] nomecolonna1,nomecolonna2…… FROM nometabella1,nometabella2 ….. [WHERE condizioni] [GROUP BY nomecolonna1, nomecolonna2,…] [HAVING condizioni su gruppi] [ORDER BY nomecolonna1, nomecolonna2,…] Delle clausole presenti nella SELECT solo la clausola FROM è obbligatoria. Analizziamo di seguito, attraverso degli esempi la sintassi del verbo SELECT. 2.4.4.1 Lettura esaustiva Accanto alla SELECT deve essere specificato l’elenco delle colonne che si vogliono visualizzare. Se si vogliono visualizzare tutte le colonne si può usare il simbolo * . Quindi per leggere tutte le colonne di una tabella si scrive: 18 Appunti del Prof. Di Capua Giuseppe SELECT * FROM Studenti Il risultato di questa query (interrogazione) è la tabella presentata a lato. Nella clausola FROM si scrive il nome della tabella da cui selezionare i dati. La clausola ALL consente di includere nella selezione tutte i record (tuple) che soddisfano la condizione. Per default, il verbo SELECT usa la clausola ALL. 2.4.4.2 Lettura di colonne (operazione di Proiezione) Se si vogliono leggere solo alcune colonne della tabella si scrive: SELECT Matricola, Cognome FROM Studenti Il risultato è la tabella a lato. Analogamente potremmo scrivere: SELECT dipnum FROM Impiegati Ottenendo la tabella a lato . Se si vuole selezionare la colonna dipnum visualizzando solo i codici distinti si aggiunge la clausola DISTINCT . Quindi scrivendo: SELECT DISTINCT dipnum FROM Impiegati si otterrà la tabella: 19 Appunti del Prof. Di Capua Giuseppe 2.4.4.3 Selezionare righe (operazione di restrizione) Per selezionare le righe di una tabella che soddisfano determinate condizioni si usa la clausola WHERE seguita da una o più condizioni. All’interno della condizione si possono utilizzare gli operatori di confronto (=,>,<,>=,<=,<>,) e gli operatori logici (and, or, not). Se scriviamo: SELECT nome, mansione, stipendio FROM Impiegati WHERE stipendio > 1000 Otterremmo il risultato corrispondente alla tabella raffigurata a lato. Volendo selezionare i soli dipendenti ingegneri scriveremo: SELECT nome, mansione, stipendio FROM Impiegati WHERE mansione = ‘ingegnere’ Otterremo la seguente tabella : quindi il confronto tra stringhe va fatto usando racchiudendo la stringa tra apici. Oltre agli operatori di confronto si possono utilizzare anche operatori. Vediamo di seguito alcuni di essi Operatore AND Consente di selezionare le righe che soddisfano contemporaneamente a più condizioni. Per esempio se vogliamo selezionare gli impiegati che sono ingegneri e che hanno uno stipendio maggiore di 1600 scriveremo: SELECT nome, mansione, stipendio FROM Impiegati WHERE mansione = ‘ingegnere’ AND stipendio > 1600 20 Appunti del Prof. Di Capua Giuseppe ottenendo la tabella a lato. Operatore OR Consente di selezionare le righe che soddisfano almeno ad una delle condizioni indicate. Per esempio, se vogliamo selezionare gli impiegati che sono tecnici oppure che sono stati assunti dopo il 01/01/1982 scriveremo: SELECT nome, mansione, stipendio, data_ass FROM Iimpiegati WHERE mansione = ‘tecnico’ OR data_ass > #01/01/1982# Il risultato è schematizzato nella figura a lato, dove è chiaro che si tratta di tecnici o dipendenti assunti dopo il 1° gennaio 1982 La sintassi delle date con l’uso del # è tipica di Access. Altri DBMS possono gestire i confronti con le date secondo diverse modalità. Se in una stessa clausola vengono utilizzati sia l’operatore AND che l’operatore OR verrà valutato prima l’AND e poi l’OR, a meno che non vengano utilizzate delle parentesi quadre per definire un ordine diverso. Operatore BETWEEN La sintassi è: nomecolonna BETWEEN valore1 AND valore2 L’operatore BETWEEN consente di selezionare le sole righe che hanno il valore della colonna specificata in nomecolonna compreso tra valore1 e valore2. Per esempio, se vogliamo selezionare gli impiegati che hanno uno stipendio compreso tra 1000 e 2000 potremmo scrivere: SELECT nome, mansione, stipendio FROM Impiegati WHERE stipendio BETWEEN 1000 AND 2000 La tabella ottenuta è raffigurata a fianco. 21 Appunti del Prof. Di Capua Giuseppe Operatore IN La sintassi è: nomecolonna IN (listavalori) Consente di selezionare le righe che hanno il valore della colonna specificata in nomecolonna uguale ad uno dei valori indicati in listavalori . Per esempio se vogliamo selezionare gli impiegati che sono dirigenti o tecnici oppure segretarie scriveremmo: SELECT nome, mansione, stipendio FROM Impiegati WHERE mansione IN (‘dirigente’,’tecnico’,’segretaria’) Ottenendo la tabella a lato: Operatore LIKE La sintassi è: nomecolonna LIKE ‘stringa’ Consente di selezionare le righe che hanno il valore della colonna specificata in nomecolonna che trova riferimento con una certa stringa Possono essere utilizzati due metacaratteri: • • * ? trova riferimento con qualunque stringa compresa la stringa vuota trova riferimento esattamente con un singolo carattere Questi metacaratteri sono tipici di Access. Altri DBMS possono usare metacaratteri diversi come % al posto di * e _(underscore) al posto di ? Per esempio se vogliamo selezionare gli impiegati che hanno un nome che comincia con A scriveremo: SELECT nome, mansione, stipendio FROM Impiegati WHERE nome LIKE ‘A*’ Ottenendo: Se vogliamo selezionare gli impiegati che hanno un nome che comincia con A e che hanno come terza lettera la d scriveremo: SELECT nome, mansione, stipendio FROM Impiegati WHERE nome LIKE ‘A?d*’ 22 Appunti del Prof. Di Capua Giuseppe ottenendo: Operatore IS NULL La sintassi è: nomecolonna IS NULL Con l’operatore IS NULL è possibile ad esempio selezionare le righe che hanno nella colonna nomecolonna un valore nullo. In un altro caso, se si vogliono selezionare tutti gli impiegati che non hanno un premio produzione si scriverà: SELECT nome, mansione, stipendio, premio_P FROM Impiegati WHERE premio_P IS NULL Ottenendo la tabella rappresentata a fianco: Operatore NOT L’operatore NOT indica la negazione della condizione. Esso è abbinabile agli operatori visti sopra. I diversi casi possibili sono: nomecolonna NOT BETWEEN valore1 AND valore2 nomecolonna NOT IN (listavalori) nomecolonna NOT LIKE ‘stringa’ nomecolonna IS NOT NULL Il primo caso presentato consente di selezionare le righe che hanno il valore della colonna specificata in nomecolonna non compreso tra valore1 e valore2. 23 Appunti del Prof. Di Capua Giuseppe Per esempio, se vogliamo selezionare gli impiegati che hanno uno stipendio non compreso tra 1000 e 2000 scriveremmo: SELECT nome, mansione, stipendio FROM Impiegati WHERE stipendio NOT BETWEEN 1000 AND 2000 Ottenendo: 2.4.4.4 Ordinamenti Per ordinare il risultato di una interrogazione si usa la clausola ORDER BY. La sintassi è: ORDER BY nomecolonna1, nomecolonna2,.. [DESC] Per default, l’ordinamento è crescente sui valori delle colonne indicate in nomecolonna1,…. Se si vuole ordinare in maniera decrescente occorre usare l’opzione DESC. Se vogliamo leggere la tabella studenti ordinata sul cognome scriveremo: SELECT * FROM Studenti ORDER BY cognome ottenendo: Se vogliamo selezionare gli impiegati che hanno uno stipendio compreso tra 1000 e 2000 ordinati sullo stipendio scriveremo: SELECT nome, mansione, stipendio FROM Impiegati WHERE stipendio BETWEEN 1000 AND 2000 ORDER BY stipendio 24 Appunti del Prof. Di Capua Giuseppe Ottenendo: È possibile ordinare anche su più colonne e anche con ordinamenti diversi. Se vogliamo selezionare gli impiegati che hanno uno stipendio compreso tra 1000 e 2000 ordinati sulla mansione in ordine crescente e - a parità di mansione - ordinare sullo stipendio in maniera descrescente scriveremmo: SELECT nome, mansione, stipendio FROM Impiegati WHERE stipendio BETWEEN 1000 AND 2000 ORDER BY mansione, stipendio DESC Ottenendo: 2.4.4.5 Funzioni di gruppo Il linguaggio SQL è dotato di funzioni che applicate ad una colonna, calcolano un valore per ciascun gruppo selezionato dalla query. Riportiamo di seguito alcune di queste funzioni di gruppo. Funzione COUNT La sintassi di tale funzione è : COUNT([DISTINCT] nomecolonna) oppure COUNT(*) Questa funzione calcola il numero di valori presenti nella colonna nomecolonna. Se è preceduta dall’istruzione DISTINCT visualizza il numero di valori distinti presenti in nomecolonna. Se viene messo come argomento il simbolo * , allora la funzione restituisce il numero di righe selezionate per ciascun gruppo. 25 Appunti del Prof. Di Capua Giuseppe Ad esempio, se si scrive: SELECT COUNT(nome) FROM Impiegati Si otterrà il numero 15, cioè quanti sono i nomi della tabella Impiegati. Se, invece si scrive: SELECT COUNT(*) FROM Impiegati WHERE stipendio > 1000 Otterremo il numero di impiegati per i quali lo stipendio è maggiore di 1000. Tali righe, per l’esempio riportato in precedenza risultano essere in numero di 10. Funzione SUM La sintassi di tale funzione è : SUM(nomecolonna) Questa funzione restituisce la somma dei valori presenti nella colonna nomecolonna ed è applicabile evidentemente alle sole colonne contenenti valori numerici. Ad esempio, se si scrive: SELECT SUM(stipendio) FROM Impiegati Si otterrà la somma degli stipendi di tutti gli impiegati. Funzione AVG La sintassi di tale funzione è: AVG(nomecolonna) Questa funzione restituisce la media aritmetica dei valori presenti nella colonna nomecolonna. Anch’essa si applica a colonne contenenti valori numerici. Ad esempio se si scrive: SELECT AVG(voto) FROM Esami WHERE matricola = 5434 26 Appunti del Prof. Di Capua Giuseppe sarà calcolata la media dei voti d’esame della matricola 5434. Funzione MAX La sintassi di tale funzione è: MAX(nomecolonna) Questa funzione restituisce il valore più grande presente nella colonna nomecolonna di un certo gruppo di record presenti in una tabella. Si applica sia a colonne numeriche che alfanumeriche. Per esempio se si scrive: SELECT MAX(voto) FROM Esami WHERE matricola = 5434 Sarà determinato il voto più alto presente nella tabella Esami, ottenuto della matricola 5434. dalla Funzione MIN Analogamente alla funzione MAX, opera la funzione MIN, ma con la restituzione del valore più piccolo presente in un gruppo di una tabella, con riferimento all’attributo nomecolonna. La sua sintassi è semplice: MIN(nomecolonna) Ad esempio, scrivendo: SELECT MIN(stipendio) FROM Impiegati WHERE dipnum = 10 Otterremo lo stipendio minimo tra coloro presenti nella tabella Impiegati e che lavorano nel dipartimento 10 Una nota importante da tener presente è che non sono ammesse query che richiedono la visualizzazione di funzioni di gruppo insieme a colonne semplici, a meno che queste ultime non compaiono anche nella clausola GROUP BY. Ad esempio, se si vuole conoscere non solo lo stipendio più basso degli impiegati che lavorano nel dipartimento 10, ma anche il nome dell’impiegato che riceve tale stipendio, non si può scrivere: SELECT MIN(stipendio),nome FROM Impiegati WHERE dipnum = 10 27 Appunti del Prof. Di Capua Giuseppe In particolare, in questo caso, Microsoft Access visualizzerà il seguente messaggio: 2.4.4.6 Raggruppamenti Le funzioni di gruppo viste sopra sono generalmente abbinate alla clausola di raggruppamento GROUP BY, la cui sintassi è: GROUP BY nomecolonna1, nomecolonna2,… [HAVING condizionedigruppo] Un esempio chiarirà bene tale clausola che si dimostra estremamente utile nell’aiutare a realizzare interrogazioni utili sul data base. Riferendosi alla tabella Impiegati, se si vuole visualizzare il salario medio in ogni dipartimento, è necessario dapprima raggruppare i dati della tabella in base al numero del dipartimento e poi eseguire la media in ogni gruppo. Per ottenere ciò, si scriverà: SELECT dipnum, AVG(stipendio) FROM Impiegati GROUP BY dipnum Il risultato ottenuto sarà la visualizzazione, per ogni dipartimento, della media degli stipendi: Come è facile notare, il numero del dipartimento (10, 20 o 30 dell’esempio) è presente tra le colonne selezionate e ciò è necessario per effettuare il raggruppamento. La clausola GROUP BY è utilizzabile anche per effettuare raggruppamenti multipli, eseguiti cioè con più colonne. Ad esempio, se si vuole vedere il numero di dipendenti che svolgono una certa mansione nell’ambito di un certo dipartimento, si può scrivere: SELECT dipnum, mansione, COUNT(*) FROM Impiegati GROUP BY dipnum, mansione In questo caso, il raggruppamento avverrà per numero di dipartimento e per mansione (all’interno dello stesso dipartimento). Il risultato relativo agli esempi di dati riportati è visualizzato nella seguente finestra: 28 Appunti del Prof. Di Capua Giuseppe Un’ulteriore funzionalità è offerta dalla presenza della clausola HAVING che è utile per porre delle condizioni sulle funzioni di gruppo. Si supponga ad esempio di voler conoscere la mansione degli impiegati aventi uno stipendio medio maggiore di 1300. In tal caso la condizione va posta sul risultato di una funzione di gruppo. Non si può usare come in precedenza la clausola WHERE, bensì la clausola HAVING. Infatti mentre la clausola WHERE consente di inserire condizioni sulle righe della tabella, la clasuola HAVING definisce delle condizioni sui gruppi selezionati dalla query. Quindi nel caso in esame, occorre scrivere: SELECT mansione, AVG(stipendio) FROM Impiegati GROUP BY mansione HAVING AVG(stipendio) > 1300 Il risultato sarà: Le condizioni della clausola HAVING seguono le stesse regole della clausola WHERE, quindi si possono usare tutti gli operatori relazionali e/o logici visti in precedenza. 2.4.4.7 Le operazioni di Join (prodotto cartesiano) Quando si fa uso di un data base, spesso nasce la necessità di ottenere informazioni provenienti da diverse tabelle. In questi casi, bisogna far ricorso ad operazioni particolari, dette join. Per poter eseguire un’operazione di join tra due (o più) tabelle occorre che ricorrano certe condizioni: innanzitutto bisogna che le tabelle da unire abbiano almeno una colonna definita sullo stesso dominio. In effetti, le join consentono di selezionare dati tra tabelle diverse legando chiavi primarie di una tabella con chiavi esterne di un’altra tabella. Ad esempio, nella tabella Impiegati il campo DipNum è una chiave esterna collegata alla chiave primaria DipNum della tabella Dipartimenti (così come è stato indicato dalla clausola FOREIGN KEY nel momento della creazione della tabella). 29 Appunti del Prof. Di Capua Giuseppe L’operazione di join, in ultima analisi equivale ad una selezione di righe non su una tabella, ma su più tabelle, risultando equivalente ad un’altra operazione, nota come prodotto cartesiano tra due tabelle. Per realizzare un prodotto cartesiano tra due tabelle basta indicare (come riportato nel prossimo esempio) nella clausola FROM il nome delle due tabelle. Se la clausola FROM è seguita da più di una tabella, è buona norma indicare nella clausola SELECT i nomi delle colonne da selezionare facendoli precedere dal nome della tabella, con la separazione del carattere “.” (es: Impiegati.nome). Tale regola, che formalmente è facoltativa, diventa obbligatoria qualora nelle tabelle in questione, vi siano colonne aventi lo stesso nome. Ad esempio, se si esegue il comando: SELECT Impid, nome, mansione, Impiegati.dipnum, nomedip FROM Impiegati, Dipartimenti si otterrà dapprima il prodotto cartesiano tra le tabelle Impiegati e Dipartimenti (attraverso la clausola FROM) con il risultato di una unica tabella virtuale avente un numero di righe pari al prodotto cartesiano delle tabelle coinvolte; dato che dopo la parola SELECT sono stati indicati 5 campi Identificativo dell’impiegato, nome, mansione, numero del dipartimento e nome del dipartimento, il risultato sarà la seguente visualizzazione: E’ evidente che il risultato non è sensato, riportando ripetizioni e dati inutili. E’ opportuno, pertanto, selezionare solo le righe significative, cioè quelle che hanno il numero di dipartimento comuni allo scopo poi di estrarre i dati necessari. 30 Appunti del Prof. Di Capua Giuseppe Si passa perciò a presentare l’operazione di join fra le due tabelle: SELECT Impid, nome, mansione,Impiegati.dipnum, nomedip FROM Impiegati, Dipartimenti WHERE Impiegati.dipnum = Dipartimenti.dipnum Si otterrà la tabella : Dato che per l’esempio proposto nella clausola WHERE è stato usato il simbolo di uguaglianza, la join esaminata viene indicata con il termine equijoin. Nel caso contrario, si sarebbe parlato di operazione non-equijoin. A scopo esemplificativo, seguono due esempi: ESEMPIO 1 Date le tabelle Esami e Studenti, si vogliano selezionare le righe con voto maggiore di 27, mostrando anche il nome dello studente ed ordinando i dati in modo crescente sul voto. In questo caso, occorre selezionare i dati da due tabelle effettuando un’operazione di join sul campo matricola: SELECT Studenti.matricola, cognome, nome, corso, voto FROM Esami, Studenti WHERE Studenti.matricola = Esami.matricola AND voto >= 27 ORDER BY voto Il risultato sarà: ESEMPIO 2 Date le tabelle Esami, Studenti, Corsi e Docenti si selezionino tutti gli esami, evidenziando il nome del docente, il nome del corso, il nome dello studente e il voto. 31 Appunti del Prof. Di Capua Giuseppe In questo caso, bisogna eseguire il comando: SELECT Corso.codcorso, descrizione, Docenti.cognome, Docenti.nome, Studenti.cognome, Studenti.nome, voto FROM Esami, Studenti, Corso, Docenti WHERE Studenti.matricola = Esami.matricola AND Esami.corso = Corsi.codcorso AND Docenti.iddocente = Corsi.iddocente Il risultato sarà: In sintesi, le due regole da rispettare per realizzare un’operazione di join sono:: • elencare nella clausola FROM i nome delle tabelle coinvolte, per realizzare il prodotto cartesiano; • specificare, nella clausola WHERE, le condizioni di join in modo da selezionare le righe significative dal prodotto cartesiano. 2.4.4.8 Le Subquery In qualche caso la risposta fornita da una certa query può essere utilizzata come condizione di un’altra query. Si supponga infatti di voler trovare tutti i dipendenti che lavorano nello stesso dipartimento del dipendente di cognome Rossi. A questa richiesta si può rispondere solo se si è a conoscenza del dipartimento di Rossi. Per sapere quale sia il dipartimento di Rossi , si dovrebbe procede al seguente comando SQL: SELECT dipnum FROM Impiegati WHERE nome = ‘Rossi’ Il risultato di questa query è 20 (il dipartimento di Rossi). A quel punto, per selezionare gli altri impiegati di questo dipartimento occorrerebbe eseguire: SELECT * FROM impiegati WHERE dipnum = 20 Questa seconda selezione sarebbe necessaria per indicare nella condizione il risultato della prima selezione. 32 Appunti del Prof. Di Capua Giuseppe I due passi precedentemente indicati possono invece essere sostituiti più efficacemente da un’unica query che contiene al suo interno un’ulteriore query, detta appunto subquery. Infatti si può scrivere: SELECT * FROM Impiegati WHERE dipnum = (SELECT dipnum FROM Impiegati WHERE nome = ‘Rossi’) ottenendo: La richiesta più interna (subquery) restituisce un numero di dipartimento alla richiesta più esterna (query principale). E’ importante notare l’uso delle parentesi che consente di separare le clausole che appartengono alla query principale da quelle che appartengono alla subquery. Seguono due esempi: ESEMPIO 1 Si vogliano selezionare tutti gli studenti che hanno un voto maggiore del voto medio tra tutti gli esami. L’istruzione SQL da eseguire è: SELECT Studenti.matricola, cognome, nome, corso, voto FROM Esami, Studenti WHERE Studenti.matricola = Esami.matricola AND voto >= (SELECT AVG(voto) FROM Esami ) Il risultato sarà: ESEMPIO 2 Si vogliono selezionare tutti i dipendenti che svolgono la mansione di Rossi e che presentano uno stipendio maggiore dello stipendio massimo dei tecnici. 33 Appunti del Prof. Di Capua Giuseppe Per ottenere il risultato desiderato, si può ricorrere alla seguente query strutturata: SELECT * FROM Impiegati WHERE mansione = (SELECT mansione FROM Impiegati WHERE nome = ‘Rossi’) AND stipendio > (SELECT MAX(stipendio) FROM Impiegati WHERE mansione = ‘tecnico’) Si otterrà: Negli esempi precedenti sono stati esaminati casi in cui la subquery restituisce un unico valore che viene poi confrontato nella condizione utilizzando gli usuali operatori relazionali. In altri casi, le subquery possono restituire anche più valori, ricorrendo ai seguenti operatori: • • • ANY e ALL EXISTS e NOT EXISTS IN e NOT IN f Operatore ANY Per utilizzare l’operatore ANY, bisogna rispettare la seguente sintassi: nomecolonna operatore ANY (Subquery) Se la subquery restituisce più valori, con ANY viene confrontato il valore di nomecolonna con tutti i valori restituiti dalla subquery. Perciò, il confronto risulta vero se almeno uno dei confronti è vero. Per comprendere appieno l’utilizzo di ANY, segue un esempio: si vogliano selezionare tutte le matricole degli studenti che hanno come voto d’esame un voto maggiore di uno degli esami sostenuti dallo studente con matricola 5434. In questo caso, si scriverà: SELECT * FROM Esami WHERE voto > ANY (SELECT voto FROM Esami WHERE matricola = 5434 ) Il risultato sarà: 34 Appunti del Prof. Di Capua Giuseppe f Operatore ALL La sintassi da rispettare è: nomecolonna operatore ALL (Subquery) La subquery restituisce più valori. L’operatore ALL confronta il valore di nomecolonna con tutti i valori restituiti dalla subquery. Il confronto risulta vero se tutti i confronti sono veri. Ad esempio, se si vogliono selezionare tutte le matricole degli studenti che hanno come voto d’esame un voto minore di tutti gli esami sostenuti dello studente matricola 5434, si avrà: SELECT * FROM Esami WHERE voto < ALL (SELECT voto FROM Esami WHERE matricola = 5434 ) Si otterrà: f Operatore EXISTS L’operatore EXISTS consente di conoscere se la subquery cui esso si riferisce restituisce almeno una riga. La sintassi è la seguente: EXISTS (Subquery) Ad esempio, se si desidera l’elenco degli esami solo se la matricola 5434 ha svolto l’esame A01, allora si può scrivere: SELECT * FROM Esami WHERE EXISTS (SELECT matricola FROM Esami WHERE matricola = 5434 AND corso = ‘A01’ ) f Operatore NOT EXIST Con l’operatore NOT EXIST si può facilmente sapere se la subquery di riferimento non restituisce alcuna riga. La sintassi è : NOT EXIST (Subquery) 35 Appunti del Prof. Di Capua Giuseppe f Operatore IN La sintassi è : nomecolonna IN (Subquery) Poiché la subquery può restituire più valori, con l’operatore IN si otterrà il valore vero se il valore di nomecolonna appartiene all’insieme dei valori restituiti dalla subquery. Ad esempio, se si vogliono visualizzare i dipendenti che hanno uno stipendio uguale a quello delle segretarie, si scriverà l’istruzione SQL: SELECT * FROM Impiegati WHERE stipendio IN (SELECT stipendio FROM Impiegati WHERE mansione = ‘segretaria’ ) ottenendo: f Operatore NOT IN L’operatore NOT IN restituisce un valore vero se il valore di nomecolonna non appartiene all’insieme dei valori restituiti dalla subquery. La sintassi è simile a quella vista precedentemente per IN : nomecolonna operatore NOT IN (Subquery) 36