Cenni storici
Modello relazionale introdotto nei laboratori IBM negli anni 70 Linguaggi per basi di dati relazionali: SEQUEL, SEQUEL/2 ed infine SQL Immediatamente adottato come standard de facto Esistono vari dialetti, che hanno un kernel condiviso
Propriet di SQL
Istruzioni per la definizione, manipolazione, controllo di un Database relazionale Istruzioni visualizzabili in modo interattivo Chiamate allinterno di un host language in cui viene realizzata lapplicazione (embedded SQL) come in PL-SQL Utilizzate allinterno di tools grafici basati su Forms (Access)
Propriet di SQL - 2
SQL manipola database relazionali La base di dati quindi costituita da Tabelle Le procedure SQL manipolano delle Tabelle e consentono di interrogare la base dati,
Diagnosi ricovero Codice Descrizione Dipendenti Codice_fisc Codice_dip Reparto Assunzione Dimissione Anzianit Codice_prof
Visite CF_Paziente Data Temp Pmax Presc CF_Med Reparti Codice Nome
Diagnosi ricovero Codice Descrizione Dipendenti Codice_fisc Codice_dip Reparto Assunzione Dimissione Anzianit Codice_prof
Visite CF_Paziente Data Temp Pmax Presc CF_Med Reparti Codice Nome
Codice_fisc
Codice_fisc
Codice_prof Reparto
Data_ingresso
Diagnosi ricovero Codice Descrizione Dipendenti Codice_fisc Codice_dip Reparto Assunzione Dimissione Anzianit Codice_prof
Visite CF_Paziente Data Temp Pmax Presc CF_Med Reparti Codice Nome
SQL e Tabelle - 1
SQL interagisce solamente con Tabelle Ad ogni intestazione di colonna associato un particolare tipo di dato e ciascuna linea contiene un valore per ogni colonna Non esiste la possibilit di inserire una tupla in un particolare ordine Le colonne si considerano ordinate allatto della creazione della tabella stessa Il nome della colonna unico: la chiave primaria del DBMS sempre user_name, table_name, column_name
SQL e Tabelle - 2
In SQL esistono tre tipi di Tabelle
Base: memorizzate nella base di dati Viste: tabelle virtuali, definite attraverso delle interrogazioni queries su altre tabelle Tabelle senza nome: tabelle restituite in seguito alla valutazione di una qualsiasi query
DATE INTEGER SMALLINT (da 32767 a 32767) FLOAT Char(n): stringa di n caratteri (da 0 a 255) Varchar(n): stringa di n caratteri (da 0 a 255 o 2048 a seconda della versione)
elimina
Esercizio
Creare ed eliminare una Tabella nel data-base di esempio. Tabella da creare: Nome: Ospedale Attributi: Citt, ASL,Posti Letto, Data_Apertura ASL e posti letto non possono essere nulli
Modificare le colonne
ALTER TABLE nome-tabella ADD nomecolonna tipo AGGIUNGE COLONNA Esercizio:
ALTER TABLE nome-tabella MODIFY nomecolonna nuovo-tipo (non disponibile in SQL per Access)
MODIFICA TIPO
Le QUERY
Interrogazione dei dati in un database Espressioni di maggiore importanza in SQL Le query vengono realizzate grazie allistruzione SELECT Il risultato di questa istruzione sempre una tabella
SELECT
Sei clausole al massimo SELECT e FROM obbligatorie Lordine delle clausole fisso Di norma la clausola HAVING si utilizza solo se presente la GROUP-BY
Restituisce una Tabella di una colonna dove sono riportati le province senza duplicati
Restituisce una Tabella con molte colonne (nb: ci sono anche campi vuoti)
Altri esempi
SELECT codice,descrizione,rimborso FROM DRG equivale a SELECT * FROM DRG
Nota bene
SQL permette di fare elaborazioni sui dati:
SELECT drg.*,round(rimborso/1936.27) AS 'EURO' FROM drg ; drg.* specifica tutte le colonne di una data tabella AS permette di (ri)nominare la colonna Composizione di colonne diverse da quelle originali utilizzando costanti, operazioni e funzioni SQL
La clausola WHERE
SELECT nome,cognome,nascita FROM generale WHERE provincia=PV;
La clausola ORDER BY
Consente di ordinare i record presentati nella tabella dei risultati secondo un ordinamento multi-livello SELECT descrizione,rimborso FROM DRG ORDER BY RIMBORSO SELECT descrizione,rimborso FROM DRG ORDER BY RIMBORSO ASC SELECT descrizione,rimborso FROM DRG ORDER BY RIMBORSO DESC
ORDER BY e WHERE
SELECT nome,cognome,nascita FROM GENERALE WHERE sesso=M AND provincia=PV ORDER BY COGNOME,NOME DESC SELECT reparto, data_ingresso, DRG FROM RICOVERI WHERE DATA_USCITA<#01/01/1980# order by codice_prof;
GROUP BY: raggruppa le righe in base ai valori uguali delle colonne specificate
HAVING: seleziona gruppi di righe che soddisfano una condizione SELECT: seleziona le colonne ORDER BY: ordina le righe secondo le colonne specificate
Ordine di elaborazione
FROM seleziona la tabella GENERALE del data-base WHERE seleziona le righe che corrispondono alla condizione sul sesso e sulla data di nascita
CODICE_FISC COGNOME NOME NASCITA SESSO CITTA PROVINCIA
F F F
F F F F F F F F F F F
PV MI PV
PV PV PV MI
CO MI PV RM NA PV MI
GROUP BY
La group by raggruppa le righe in base ai valori della colonna provincia
CODICE_FISC DFKLJF3409WDKL09 SDLDKLJKFD9SD9JK DSKSD0934JKSDJKF DFDKE309ASLDKL09 ADJPSJASGHAKS180 SDJK389SDJK3RW89 SDL3RPDLDHJSD093 KJIOESDSJKD94900 ADJPSJASGHAKS266 ADJPSJASGHAKS257 ADJPSJASGHAKS218 ADJPSJASGHAKS181 ADJPSJASGHAKS147 SAKJH3489SDJK89J COGNOME Baita Gentile Tamborra Nostrile Vassallo Ferrario Rigamonti Corsetti Fantozzi Gianotti Alessi De Luca Monti Cerri NOME Sabina Lucia Anna Cristina Ada Maria Carla Franca Maria Maria Franca Francesca Laura Antonia NASCITA 12/03/1990 28/12/1991 12/03/1989 09/12/1961 03/11/1963 26/12/1983 14/02/1983 09/11/1971 03/12/1960 11/06/1960 16/01/1963 27/04/1964 14/09/1964 12/06/1982 SESSO F F F CITTA Como Milano Rho PROVINCIA CO MI
F
F F F F F F F F F F Milano Napoli Bressana Bressana Pavia Casteggio Broni Certosa Copiano Roma RM NA PV
HAVING
E simile alla where, ma agisce sui gruppi. Nellesempio seleziona tutti i gruppi con un numero di elementi maggiore di uno (count(*))
CODICE_FISC DFKLJF3409WDKL09 SDLDKLJKFD9SD9JK DSKSD0934JKSDJKF DFDKE309ASLDKL09 ADJPSJASGHAKS180 SDL3RPDLDHJSD093 KJIOESDSJKD94900 ADJPSJASGHAKS266 ADJPSJASGHAKS257 ADJPSJASGHAKS218 ADJPSJASGHAKS181 ADJPSJASGHAKS147 COGNOME Baita Gentile Tamborra Nostrile Vassallo Rigamonti Corsetti Fantozzi Gianotti Alessi De Luca Monti NOME Sabina Lucia Anna Cristina Ada Carla Franca Maria Maria Franca Francesca Laura NASCITA 12/03/1990 28/12/1991 12/03/1989 09/12/1961 03/11/1963 14/02/1983 09/11/1971 03/12/1960 11/06/1960 16/01/1963 27/04/1964 14/09/1964 SESSO F F CITTA Como Milano Rho PROVINCIA CO MI
F
F F F F
F
F F F F
SELECT e ORDER BY
Seleziona le colonne. La SELECT in questo caso pu selezionare soltanto le colonne con il medesimo valore per ogni gruppo, o su cui si siano effettuate delle funzioni di aggregazione. Nel nostro caso vengono selezionate le province La ORDER BY ordina i risultati in ordine alfabetico
provincia MI PV
Se avessimo voluto recuperare anche la colonna della data di nascita, avremmo dovuto introdurre nella SELECT un operatore di aggregazione, ad es. max: (select max(data_di_nascita )
max_nasc 28/12/1991 14/02/1983 provincia MI PV
Gruppi
La clausola GROUP BY raggruppa le righe della tabella derivata dallapplicazione delle clausole FROM e WHERE suddividendole in base ai valori della colonna specificata Ovviamente i gruppi possono avere colonne con pi di un valore La colonna di raggruppamento, viceversa, avr pi di un valore La clausola HAVING equivalente alla WHERE ma agisce solo sui dati raggruppati Nella SELECT possono solo comparire funzioni di aggregazione e/o colonne presenti nella GROUP BY
Join
Si ha una JOIN fra tabelle quando nella clausola FROM viene referenziata pi di una tabella, e nella clausola WHERE presente una condizione che confronta tabelle diverse. Esempio: quale il nome e cognome dei dipendenti dellospedale? Soluzione: SELECT DISTINCT generale.nome, generale.cognome, dipendenti.codice_prof FROM generale,dipendenti WHERE dipendenti.codice_fisc=generale.codice_fisc
Esercizio
Trovare il nome ed il cognome dei primari dellospedale nei diversi reparti Soluzione
SELECT generale.nome,generale.cognome,reparti.nome,professioni .descrizione FROM generale,dipendenti, reparti, professioni WHERE professioni.descrizione='primario and dipendenti.codice_prof=professioni.codice and dipendenti.codice_fisc=generale.codice_fisc and dipendenti.reparto=reparti.codice
Diagnosi ricovero Codice Descrizione Dipendenti Codice_fisc Codice_dip Reparto Assunzione Dimissione Anzianit Codice_prof
Visite CF_Paziente Data Temp Pmax Presc CF_Med Reparti Codice Nome
Join e subqueries
Esempio: trovare gli elementi della tabella di anagrafica fra loro coetanei Non posso usare listruzione GROUP BY: non riesco a farmi restituire i nomi dei soggetti Select nascita, count(*) from generale group by nascita having count(*)>2
Soluzioni
Join della tabella con se stessa
SELECT DISTINCT gen1.nome, gen1.cognome, gen1.nascita FROM generale gen1, generale gen2 where gen1.nascita=gen2.nascita and gen1.codice_fisc<>gen2.codice_fisc order by gen1.nascita
Query annidate
SELECT gen1.nome, gen1.cognome, gen1.nascita FROM generale gen1 where gen1.nascita in (select gen2.nascita from generale gen2 group by gen2.nascita having count(nascita)>=2) order by gen1.nascita
SELECT nome, cognome, nascita from generale where nascita between #01/01/1960# AND #01/01/1964#
SELECT nome, cognome, nascita from generale where citta like B* cerca tutte le citt che iniziano con la lettera B SELECT nome, cognome, provincia from generale where provincia in ('AL','LO') order by provincia
Esempio di subquery correlata: si referenziano delle colonne che sono state introdotte nella query precedente
Esercizi
Nome dei pazienti ricoverati nel reparto di medicina interna
select g.nome,g.cognome from generale g, ricoveri r where g.codice_fisc = r.codice_fisc and reparto in (select reparti.codice from reparti where reparti.nome='Medicina Interna') order by g.cognome
Esercizi
Nome dei primari dei vari reparti
select distinct g.nome,g.cognome,r.nome from generale g, dipendenti d, reparti r where g.codice_fisc = d.codice_fisc and d.reparto=r.codice and d.codice_prof in (select professioni.codice from professioni where professioni.descrizione='Primario') order by g.cognome
Funzioni di aggregazione
COUNT(*): restituisce il numero di record presenti nellaggregato COUNT(), MIN(), MAX() possono essere utilizzati su tutti i campi SUM e AVG si possono utilizzare su campi numerici Esempio: la data di nascita pi recente nella tabella di anagrafica Select max(nascita) from generale
Esercizio
Si trovi il minimo, il massimo, il totale e la media degli stipendi percepiti ed il numero di dipendenti in ogni classe stipendiale NB: la retribuzione calcolata come anzianit * retribuzione base /100
SELECT p.DESCRIZIONE, Min(p.retrib_base*anzianita/100) AS minimo, Max(p.retrib_base*anzianita/100) AS massimo, Avg(p.retrib_base*d.anzianita/100) AS media, Count(*) AS numero FROM dipendenti AS d, professioni AS p WHERE (((d.CODICE_PROF)=[p].[codice])) GROUP BY p.DESCRIZIONE, p.CODICE;
UPDATE e DELETE
Creiamo una tabella di prova
SELECT * into temp from professioni
Sostituiamo le lire con gli Euro update temp set retrib_base=retrib_base/1936.27 where retrib_base is not null Togliamo le righe nulle delete from temp where retrib_base is null
UNION
Mediante UNION si possono specificare pi tabelle in un unico risultato Le tabelle sorgenti devono avere lo stesso numero di colonne e lo stesso tipo dei dati SELECT nome,costo from prescrizioni UNION SELECT descrizione,rimborso from drg; In assenza della direttiva ALL vengono rimossi i duplicati
VISTE
Tabelle virtuali. Il loro contenuto ricavato da altre tabelle mediante una query Viene memorizzata la struttura della query e rieseguita ogni volta In ACCESS le query salvate possono essere considerate delle viste Si possono effettuare delle query su viste In altri DBMS esiste il comando CREATE VIEW che permette di effettuare la medesima operazione
Esercizi
1. Si trovi qual il numero totale dei suoi
ricoveri e in quali e quanti reparti stato ricoverato ciascun paziente 2. Si trovino i reparti che hanno ricoverato pi persone 3. Si inserisca una nuova professione nella tabella delle professioni senza sapere lultimo numero assegnato 4. Si trovi chi viene pagato pi della media di categoria
Esercizio
Si trovi nome, cognome, reparto del pi anziano dipendente dellospedale select g.nome, g.cognome, g.nascita, rep.nome,d.codice_dip from generale g, dipendenti d, reparti rep where nascita in (SELECT min(nascita) from generale as g, dipendenti as d where g.codice_fisc=d.codice_fisc) and g.codice_fisc=d.codice_fisc and rep.codice=d.reparto
Esercizio 1
SELECT nome, cognome, count(*) as numero FROM ricoveri r, generale g WHERE g.codice_fisc=r.codice_fisc GROUP BY r.codice_fisc, nome, cognome SELECT distinct g.nome,g.cognome, g.codice_fisc, rep.nome into test1 FROM ricoveri as r, generale as g, reparti as rep WHERE r.codice_fisc=g.codice_fisc and rep.codice=r.reparto ORDER BY cognome; SELECT t.nome, t.cognome, count(*) as numero_reparti FROM test1 as t GROUP BY t.codice_fisc t.cognome, t.nome;
Esercizio 2
SELECT reparti.nome, count(*) AS numero_ricoveri from ricoveri,reparti where codice=reparto group by reparto, reparti.nome having count(*)>1
Esercizio 3
INSERT into professioni select max(codice_prof)+1, Nuova from professioni
Esercizio 4
SELECT nome,cognome, p.descrizione, (p.retrib_base*d.anzianita/100) as retribuzione, (SELECT Avg(p1.retrib_base*d1.anzianita/100) FROM dipendenti d1, professioni as p1 WHERE d1.codice_prof=p.codice and d1.CODICE_PROF=d.codice_prof) as media FROM generale g, professioni p, dipendenti d WHERE d.codice_prof=p.codice and d.codice_fisc=g.codice_fisc and (p.retrib_base*d.anzianita/100) > (SELECT Avg(p1.retrib_base*d1.anzianita/100) FROM dipendenti d1, professioni as p1 WHERE d1.codice_prof=p1.codice and d1.CODICE_PROF=d.codice_prof);