08.01.2015 Views

Esercizi svolti - SisInf Lab

Esercizi svolti - SisInf Lab

Esercizi svolti - SisInf Lab

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

RISOLUZIONE APPELLI<br />

DI<br />

SISTEMI INFORMATIVI<br />

a cura di<br />

E. Di Sciascio ed E. Tinelli


CONSIDERAZIONI PRELIMINARI ................................................................................................. 3<br />

APPELLO 28 LUGLIO 2006 ........................................................................................................... 4<br />

<strong>Esercizi</strong>o a ................................................................................................................................. 4<br />

<strong>Esercizi</strong>o b ................................................................................................................................. 6<br />

<strong>Esercizi</strong>o c ................................................................................................................................. 7<br />

<strong>Esercizi</strong>o d ................................................................................................................................. 8<br />

APPELLO 17 FEBBRAIO 2006 ...................................................................................................... 9<br />

<strong>Esercizi</strong>o a ................................................................................................................................. 9<br />

<strong>Esercizi</strong>o b ............................................................................................................................... 11<br />

<strong>Esercizi</strong>o c ............................................................................................................................... 12<br />

<strong>Esercizi</strong>o d ............................................................................................................................... 13<br />

APPELLO 12 FEBBRAIO 2008................................................................................................... 14<br />

<strong>Esercizi</strong>o a............................................................................................................................... 14<br />

<strong>Esercizi</strong>o b............................................................................................................................... 16<br />

<strong>Esercizi</strong>o c ............................................................................................................................... 17<br />

<strong>Esercizi</strong>o d............................................................................................................................... 18<br />

Esempi di Normalizzazione........................................................................................................... 19<br />

1) Appello 7 Aprile 2006 .......................................................................................................... 19<br />

2) Appello 23 Giugno 2006...................................................................................................... 21<br />

3) Appello 28 Settembre 2006................................................................................................. 22<br />

ESEMPI di query SQL.................................................................................................................. 23<br />

1) Appello 21 Novembre 2006................................................................................................. 23<br />

2) Appello 28 Settembre 2006................................................................................................. 24<br />

3) Appello 24 Settembre 2005 ed Esempi vari ........................................................................ 25


CONSIDERAZIONI PRELIMINARI<br />

1. Si osservi che generalmente non esiste una soluzione unica per la risoluzione di un appello.<br />

Pertanto le risoluzioni qui proposte rappresentano esclusivamente un esempio di buone<br />

pratiche, mA non escludono altre risoluzioni formalmente e sostanzialmente corrette. In questo<br />

eserciziario, pertanto, si illustra una delle possibili soluzioni.<br />

2. L’esercizio b va svolto scrivendo le CREATE TABLE corrispondenti a ciascuna relazione del<br />

modello E-R dell’esercizio a. Per semplicità, in questo eserciziario, riportiamo il risultato del<br />

mapping in forma tabellare ed esplicitiamo in SQL solamente le relazioni più complesse.<br />

3. Quando nell’esercizio a si individua un attributo calcolato (o attributo derivato) è possibile<br />

(ma non necessario) scrivere nell’esercizio b, senza ricorrere all’uso dei trigger, la query SQL<br />

che servirebbe per calcolare il suddetto attributo.<br />

4. Per business rules si intendono quelle regole che è necessario verificare e che non possono<br />

essere espresse nel modello E-R. Generalmente tali regole possono essere espresse in SQL<br />

nell’esercizio b mediante check , assertion e trigger.<br />

5. L’esercizio c può essere svolto secondo i seguenti 2 approcci:<br />

- trovare prima la chiave della tabella(anche procedendo per tentativi) e quindi le eventuali<br />

dipendenze piene dalla chiave, le dipendenze parziali e/o transitive dalla chiave;<br />

- trovare tutte le dipendenze funzionali in base alla semantica dei dati ed alle ipotesi del<br />

problema e poi individuare la chiave della tabella.<br />

In questo eserciziario si utilizza il secondo approccio.


APPELLO 28 LUGLIO 2006<br />

<strong>Esercizi</strong>o a<br />

Si progetti uno schema concettuale Entità-Relazioni per lo scenario più sotto descritto.<br />

Una base di dati deve essere utilizzata per gestire gli ordini di un’azienda che produce PC ed<br />

organizzarne la produzione.<br />

Bisogna tener traccia dei dettaglianti che effettuano gli ordini dei PC e dei fornitori che<br />

forniscono i componenti necessari all’azienda per assemblare i PC. Sia i dettaglianti che i fornitori<br />

sono caratterizzati dai seguenti dati: partita iva, ragione sociale, indirizzo, telefono ed e-mail.<br />

Sia i PC che i loro componenti sono caratterizzati da un codice univoco, un nome ed un prezzo.<br />

Inoltre, per i componenti è necessario memorizzare il fornitore di riferimento, mentre per i PC il<br />

numero di pezzi (minore o uguale a 30) ed i componenti che li costituiscono. Bisogna verificare<br />

anche che il numero di pezzi sia inferiore a 20 se il prezzo del PC è inferiore a 1000 euro.<br />

È necessario, infine, tenere traccia dei seguenti eventi:<br />

- gli ordini dei PC da parte dei dettaglianti caratterizzati dalla data ed ora dell’ordine, dalla data di<br />

consegna pattuita, dal tipo di pagamento (anticipato, alla consegna, a 30 gg) e dai PC ordinati con<br />

le relative quantità;<br />

- il processo di assemblaggio di un PC caratterizzato dalla data ed ora di inizio del processo,<br />

dall’ora di fine e dal dipendente che si occupa dell’assemblaggio.<br />

Ciascun dipendente è caratterizzato dai seguenti dati: codice fiscale, nome, cognome, data di<br />

nascita e di assunzione.<br />

Indicare le cardinalità delle relazioni e un identificatore per ciascuna entità.<br />

Osservazioni:<br />

1)Le due entità fornitore e dettagliante sono caratterizzate dagli stessi dati ma non è necessario<br />

modellare una gerarchia costituita nel seguente modo:<br />

- entità padre: azienda<br />

- entità figlie: fornitore e dettagliante.<br />

Il motivo è il seguente: le altre entità del modello fanno riferimento all’entità fornitore oppure<br />

all’entità dettagliante ma mai ad una generica azienda, pertanto la gerarchia doveva risolversi<br />

portando i figli nel padre. Il risultato è quindi quello di avere nel modello E-R due entità distinte<br />

fornitore e dettagliante ciascuna con i sui attributi e le sue relazioni.<br />

2) Le due entità PC e componente sono caratterizzate da alcuni dati in comune, in particolare dalla<br />

chiave codice, ma non è necessario modellare una gerarchia costituita nel seguente modo:<br />

- entità padre: prodotto<br />

- entità figlie: PC e componente.<br />

Considerando che un pc ed un componente non sono “materialmente” la stessa cosa (difatti un pc è<br />

costituito dall’insieme dei componenti) e che le altre entità del modello fanno sempre riferimento<br />

all’entità PC oppure all’entità componente ma mai ad un generico prodotto, una eventuale gerarchia<br />

doveva risolversi portando i figli nel padre. Anche in questo caso il risultato è quello di avere nel<br />

modello E-R due entità distinte PC e componente ciascuna con i sui attributi e le sue relazioni.


Business rules:<br />

1. il numero di pezzi deve essere minore o uguale a 30;<br />

2. il numero di pezzi deve essere inferiore a 20 quando il prezzo del PC è inferiore a 1000<br />

euro;<br />

3. il tipo di pagamento può assumere i seguenti 3 valori: ‘anticipato‘, ‘alla consegna’, ‘a 30<br />

gg’.


<strong>Esercizi</strong>o b<br />

Si definiscano le relazioni (tabelle) risultanti in SQL, avendo cura di esplicitare i vincoli di integrità.<br />

DETTAGLIANTE ( PIVA, ragione_sociale, indirizzo, Tel, e-mail )<br />

FORNITORE ( PIVA, ragione_sociale, indirizzo, Tel, e-mail )<br />

PC ( codice, nome, prezzo, N_pezzi )<br />

COMPONENTE ( codice, nome, prezzo, PIVA_fornitore )<br />

PC_componente ( codicePC, codiceComp )<br />

ORDINE ( data, ora, PIVA_dett, data_consegna, tipo_pagamento )<br />

ORDINE_PC ( data, ora, PIVA_dett, codicePC, quantità )<br />

DIPENDENTE ( CF, nome, cognome, data_nascita, data_assunzione )<br />

ASSEMBLAGGIO ( data_in, ora_in, CF_dipendente, codicePC, ora_fine )<br />

CREATE TABLE PC<br />

( codice char (8) primary key,<br />

nome varchar(30) NOT NULL,<br />

prezzo numeric (7,2) NOT NULL,<br />

N_pezzi int check ( N_pezzi < = 30 ),<br />

check ( N_pezzi >=20 OR (N_pezzi


<strong>Esercizi</strong>o c<br />

Si vuole realizzare un database relativo alla organizzazione dei provini delle Agenzie di casting<br />

italiane. E’ stata a tal fine costruita, da un inesperto progettista, una unica tabella descritta dai<br />

seguenti attributi:<br />

(PIVA_agenzia, nome_agenzia, indirizzo, tel, CF_partecipante, nome, cognome, data_nascita,<br />

e_mail, codice_materiale_partecipante, descr_materiale, num_foto, città_provino,<br />

nome_hotel_provino, data_provino, ora_provino, tipo_provino, esito_provino)<br />

Nell’ipotesi che ciascun provino è organizzato da un’agenzia e che una stessa persona possa<br />

partecipare a più provini, se ne determini la chiave e si individuino, esplicitandole, le dipendenze<br />

funzionali. Sulla base di queste si proceda alla normalizzazione in 3° forma normale, preservando le<br />

dip. Funzionali.<br />

Dominio\semantica dei dati: organizzazione dei provini delle Agenzie di casting italiane.<br />

Ipotesi della traccia: ciascun provino è organizzato da un’agenzia ed una stessa persona può<br />

partecipare a più provini<br />

Il dominio dei dati e le ipotesi forniscono le seguenti considerazioni: il dominio dei dati indica che è<br />

necessario individuare le agenzie ed i provini mentre secondo le ipotesi della traccia chi li organizza e<br />

chi vi partecipa.<br />

Primo passo: trovare tutte le dipendenze funzionali in accordo al dominio ed alle ipotesi. Passare alla<br />

seconda forma normale individuando eventuali attributi composti. In questo esercizio l’attributo<br />

indirizzo può essere considerato composto dai seguenti attributi: via, N_civico e CAP<br />

1) PIVA_agenzia nome_agenzia, via, N_civico, CAP, tel<br />

2) CF_partecipante nome, cognome, data_nascita, e-mail, codice_materiale_partecipante<br />

3) codice_materiale_partecipante descr_materiale, num_foto<br />

Ipotesi: consideriamo che un’agenzia in una città possa organizzare solo 1 provino al giorno.<br />

4) PIVA_agenzia, città_provino, data_provino nome_hotel_provino, tipo_provino<br />

Ipotesi: consideriamo ora_provino come l’ora in cui inizia la prova di ciascun partecipante.<br />

5) PIVA_agenzia, città_provino, data_provino, CF_partecipante ora_provino, esito_provino<br />

Secondo passo: individuare la chiave della tabella.<br />

In base alle dipendenze trovate ipotizziamo come chiave della tabella PIVA_agenzia, città_provino,<br />

data_provino, CF_partecipante<br />

Se tutte le dipendenze precedenti possono essere classificate rispetto alla suddetta chiave in uno dei<br />

seguenti modi:<br />

• dipendenza piena (la dip. 5);<br />

• dipendenza parziale (la dip. 1, 2, 4);


• dipendenza transitiva (la dip. 3);<br />

allora l’esercizio è svolto correttamente.<br />

Le tabelle risultanti sono:<br />

AGENZIA (PIVA_agenzia, nome_agenzia, via, N_civico, CAP, tel)<br />

PARTECIPANTE (CF_partecipante, nome, cognome, data_nascita, e-mail, codice_materiale_partecipante)<br />

MATERIALE (codice_materiale_partecipante, descr_materiale, num_foto)<br />

PROVINO (PIVA_agenzia, città_provino, data_provino, nome_hotel_provino, tipo_provino)<br />

PARTECIPA_PROVINO (PIVA_agenzia, città_provino, data_provino, CF_partecipante, ora_provino,<br />

esito_provino)<br />

<strong>Esercizi</strong>o d<br />

Date le seguenti relazioni:<br />

PROGETTO(Codice, nome, importo_mensile, data_inizio, data_consegna)<br />

DIPENDENTE(CF, nome, cognome, data_nascita, data_assunzione)<br />

LAVORA_SU(Codice, CF, num_ore, ruolo)<br />

esprimere in SQL le seguenti interrogazioni:<br />

1) Estrarre i responsabili dei progetti con un importo annuale superiore a 10000 euro ed un numero di<br />

ore complessivo superiore a 1000.<br />

SELECT distinct CF<br />

FROM LAVORA_SU natural join PROGETTO<br />

WHERE importo_mensile*12 > 10000<br />

AND ruolo = ‘responsabile’<br />

AND codice IN ( SELECT codice<br />

FROM LAVORA_SU<br />

GROUP BY codice<br />

HAVING sum(num_ore) > 1000 )<br />

2) Per ciascun dipendente, estrarre il numero di progetti su cui lavora attualmente con qualifica di<br />

‘programmatore’.<br />

SELECT CF, count(*)<br />

FROM LAVORA_SU natural join PROGETTO<br />

WHERE ruolo = ‘programmatore’<br />

AND data_inizio = ‘28/07/2006’<br />

GROUP BY CF


APPELLO 17 FEBBRAIO 2006<br />

<strong>Esercizi</strong>o a<br />

Si progetti uno schema concettuale Entità-Relazioni per lo scenario più sotto descritto.<br />

Una base di dati deve essere utilizzata dal comune di Bari per gestire alcuni dati relativi ai suoi<br />

cittadini.<br />

Ciascun cittadino è caratterizzato da un codice fiscale, dal nome e dal cognome, dalla data e dal<br />

comune di nascita, dal numero di telefono e dalla residenza. Inoltre, per ciascun cittadino,<br />

interessa conoscere i seguenti dati che ne definiscono il percorso formativo: occupazione attuale,<br />

titolo di studio con relativa votazione, elenco degli eventuali attestati posseduti con relativa data di<br />

conseguimento.<br />

Per gestire la sezione “Anagrafe” del comune, è necessario memorizzare i seguenti dati:<br />

i genitori di ciascun cittadino, i matrimoni e la relativa data, considerando che ciascun cittadino<br />

può sposarsi più volte ma non con la stessa persona.<br />

Per gestire la sezione “Catasto” del comune, è necessario memorizzare le proprietà di ciascun<br />

cittadino che sono caratterizzate da un identificativo catastale, una descrizione, un valore<br />

economico ed una categoria catastale (unità abitativa, unità commerciale, terreno). Per l’unità<br />

abitativa si deve tener traccia del numero di vani,mentre, per l’unità commerciale ed il terreno, la<br />

superficie (espressa in mq).<br />

Per gestire la sezione “Sanità” del comune, è necessario memorizzare le malattie particolarmente<br />

infettive da cui è attualmente, oppure è stato affetto, ciascun cittadino indicando, per ognuna, la<br />

data di inizio della cura e l’eventuale data di guarigione. Ciascuna malattia è identificata da un<br />

nome univoco, una descrizione, una classe (con valore non superiore a 4) e dal principio attivo che<br />

la cura. Si ipotizzi che nessun cittadino possa avere, per più di una volta, la stessa malattia.<br />

Indicare le cardinalità delle relazioni e un identificatore per ciascuna entità.<br />

Osservazioni:<br />

• Le ipotesi della traccia su matrimonio (ciascun cittadino può sposarsi più volte ma non con la<br />

stessa persona) e malattia (nessun cittadino può avere, per più di una volta, la stessa malattia)<br />

ci permettono di utilizzare delle relazioni N : N.<br />

• L’entità PERCORSO FORMATIVO non è necessaria poichè è possibile assegnare tutti i suoi<br />

attributi e relazioni direttamente all’entità CITTADINO.<br />

• L’espressione eventuale guarigione della traccia indica che il campo data_guarigione può<br />

essere NULL.<br />

• La specifica che la superficie è espressa in mq è un’indicazione per il tipo di dato in SQL da<br />

utilizzare per il campo mq nell’esercizio b.


Risoluzione della gerarchia: Aggiungere un attributo tipo (unità abitativa, terreno, unità<br />

commerciale) all’entità PROPRIETÀ e portare gli attributi dei figli (N_vani, mq) nell’entità padre.<br />

Per essere più precisi dovremmo aggiungere un ulteriore vincolo (check) chiedendo che:<br />

- N_vani ha un valore quando tipo = ‘unità abitativa’<br />

- Mq ha un valore quando tipo = ‘terreno’ oppure tipo = ‘unità commerciale’<br />

Business rules:<br />

1. la classe non può assumere un valore superiore a 4.<br />

2. tipo può assumere solo i 3 valori: ‘unità abitativa’, ‘terreno’, ‘unità commerciale’.


<strong>Esercizi</strong>o b<br />

Si definiscano le relazioni (tabelle) risultanti in SQL, avendo cura di esplicitare i vincoli di integrità.<br />

CITTADINO (CF, nome, cognome, data_nascita, comune_ nascita, residenza, tel, CF_padre,<br />

CF_madre)<br />

MATRIMONIO (CF_marito, CF_moglie, data)<br />

PERCORSO_FORMATIVO ( CF, occupazione, titolo, voto)<br />

ATTESTATO ( ID, NOME)<br />

PERCORSO_ATTESTATO ( CF, ID, data)<br />

PROPRIETÀ (ID_catasto, descrizione, valore, tipo, N_vani, mq, CF_proprietario)<br />

MALATTIA ( nome, descrizione, classe)<br />

CITTADINO_MALATTIA ( CF, malattia, data_inizio, data_guarigione)<br />

CREATE TABLE CITTADINO<br />

( CF char(16) primary key,<br />

nome varchar(30),<br />

cognome varchar(20),<br />

data_nascita date,<br />

comune_nascita varchar(50),<br />

residenza varchar(100),<br />

tel varchar(15),<br />

CF_padre char(16) references CITTADINO(CF),<br />

CF_madre char(16) references CITTADINO(CF) )<br />

CREATE TABLE PERCORSO_FORMATIVO<br />

( CF char(16) primary key,<br />

occupazione varchar(50),<br />

titolo varchar(50),<br />

voto smallint,<br />

foreign key(CF) references CITTADINO(CF)<br />

)<br />

CREATE TABLE PROPRIETÀ<br />

( ID_catasto char(10) primary key,<br />

descrizione varchar(100),<br />

valore numeric(9,2),<br />

tipo varchar (17) check (tipo IN (‘unità abitativa’, ‘terreno’, ‘unità commerciale’),<br />

N_vani smallint,<br />

mq float,<br />

CF_proprietario char(16) references CITTADINO(CF),<br />

check ( (N_vani IS NOT NULL AND tipo = ‘unità abitativa’) OR (mq IS NOT NULL AND tipo<br />

IN (‘terreno’,‘unità commerciale’)) )<br />

)


<strong>Esercizi</strong>o c<br />

Si vuole realizzare un database relativo alla alle programmazioni dei films delle reti televisive<br />

italiane. E’ stata a tal fine costruita, da un inesperto progettista, una unica tabella descritta dai<br />

seguenti attributi:<br />

(cod_film, titolo, regista, anno_produzione, data_programmazione_film, ora_inizio, ora_fine,<br />

nome_reteTV, tipo_rete, cod_pubblicità, nome_pubblicità, ora_trasmissione_pubblicità, durata)<br />

Considerando che alla programmazione di un film possono essere assegnate le stesse pubblicità,<br />

si determini la chiave della tabella e si individuino, esplicitandole, le dipendenze funzionali. Sulla<br />

base di queste si proceda alla normalizzazione in 3° forma normale, preservando le dip. Funzionali.<br />

Dominio\semantica dei dati: programmazioni dei films delle reti televisive italiane.<br />

Ipotesi della traccia: alla programmazione di un film possono essere assegnate le stesse pubblicità<br />

Il dominio dei dati e le ipotesi forniscono le seguenti considerazioni: il dominio dei dati indica che è<br />

necessario individuare i films, le reti televisive e le relative programmazioni mentre secondo le ipotesi<br />

della traccia le pubblicità e quando vengono trasmesse allinterno di un film in programmazione.<br />

Primo passo: trovare tutte le dipendenze funzionali in accordo al dominio ed alle ipotesi. Passare alla<br />

seconda forma normale individuando eventuali attributi composti.<br />

1) cod_film titolo, regista, anno_produzione<br />

2) nome_reteTV tipo_rete<br />

3) cod_pubblicità nome_pubblicità, durata<br />

Ipotesi: consideriamo che un film non possa essere trasmesso su una stessa rete più volte al giorno.<br />

4) cod_film, nome_reteTV, data_programmazione_film ora_inizio, ora_fine<br />

Ipotesi: consideriamo l’ipotesi della traccia.<br />

5) cod_film, nome_reteTV, data_programmazione_film, ora_trasmissione_pubblicità<br />

cod_pubblicità<br />

Secondo passo: individuare la chiave della tabella.<br />

Si verifichi che, se la chiave della tabella è cod_film, nome_reteTV, data_programmazione_film,<br />

ora_trasmissione_pubblicità, tutte le dipendenze funzionali precedenti possono essere classificate<br />

rispetto alla suddetta chiave in uno dei seguenti modi: dipendenza piena, dipendenza parziale,<br />

dipendenza transitiva.<br />

Le tabelle risultanti sono:<br />

FILM (cod_film, titolo, regista, anno_produzione)<br />

RETE (nome_reteTV, tipo_rete)<br />

PUBBLICITÀ (cod_pubblicità, nome_pubblicità, durata)


PROGRAMMAZIONE_FILM (cod_film, nome_reteTV, data_programmazione_film, ora_inizio,<br />

ora_fine)<br />

PROGRAMMAZIONE_PUBBLICITÀ (cod_film, nome_reteTV, data_programmazione_film,<br />

ora_trasmissione_pubblicità, cod_pubblicità)<br />

<strong>Esercizi</strong>o d<br />

Date le seguenti relazioni:<br />

PERSONA(CF, nome, cognome, data_nascita)<br />

CORSA(N_linea, ora_partenza, comune_partenza, ora_arrivo, comune_arrivo, num_km)<br />

PRENOTAZIONE(codice, data_prenotazione, CF, N_linea, ora_partenza, costo)<br />

esprimere in SQL le seguenti interrogazioni:<br />

1) Estrarre il comune di partenza, il comune di arrivo e la durata di tutte le corse prenotate da ‘Mario<br />

Rossi’.<br />

SELECT comune_partenza, comune_arrivo, ora_arrivo – ora_partenza<br />

FROM CORSA<br />

WHERE (N_linea, ora_partenza) IN ( SELECT N_linea, ora_partenza<br />

FROM PRENOTAZIONE natural join PERSONA<br />

WHERE nome = ‘Mario’<br />

AND cognome = ‘Rossi’<br />

)<br />

2) Estrarre i viaggiatori che hanno prenotato una stessa corsa almeno 2 volte ma mai una corsa in<br />

partenza da ‘Bari’.<br />

SELECT *<br />

FROM Persona<br />

WHERE CF IN ( SELECT distinct P1.CF<br />

FROM PRENOTAZIONE P1, PRENOTAZIONE P2<br />

WHERE P1.N_linea = P2.N_linea<br />

AND P1.ora_partenza = P2.ora_partenza<br />

AND P1.CF = P2.CF<br />

AND P1.codice P2.codice<br />

)<br />

AND CF NOT IN ( SELECT distinct CF<br />

FROM PRENOTAZIONE natural join CORSA<br />

WHERE comune_partenza = ‘Bari’<br />

)


APPELLO 12 FEBBRAIO 2008<br />

<strong>Esercizi</strong>o a<br />

Si progetti uno schema concettuale Entità-Relazioni per lo scenario più sotto descritto.<br />

Una base di dati deve essere utilizzata per gestire il calendario delle partite del prossimo campionato<br />

di calcio di serie A e di serie B.<br />

Bisogna, pertanto, tener traccia delle seguenti informazioni: gli stadi italiani, le squadre di calcio, i<br />

calciatori tesserati e le partite disputate. In particolare, si consideri che:<br />

• i calciatori che partecipano al campionato sono caratterizzati dai seguenti dati: numero di tessera,<br />

nome e cognome, data e paese di nascita. A ciascun giocatore è associato eventualmente un fan<br />

club di cui si vuole tener traccia mediante i seguenti dati: numero di iscritti, data di creazione,<br />

quota di partecipazione e sito internet;<br />

• gli stadi utilizzati durante il campionato che sono caratterizzati dai seguenti dati: codice<br />

alfanumerico univoco, nome, capienza e città;<br />

• le squadre che partecipano al campionato che sono caratterizzate dai seguenti dati: identificativo<br />

univoco, nome ed eventuale numero di scudetti vinti.<br />

Per gestire il calendario è necessario tener traccia delle partite disputate, che possono essere di serie A<br />

oppure di serie B, e che sono, inoltre, caratterizzate dai seguenti dati: data della partita, ora di inizio<br />

ed ora di fine, punteggio parziale alla fine del primo tempo e punteggio finale. Si osservi che è<br />

necessario verificare che ciascun punteggio sia costituito da una sequenza di caratteri di questo tipo<br />

‘0:0’. A ciascuna partita bisogna, inoltre, associare lo stadio di riferimento, la squadra che gioca in<br />

casa, la squadra ospite, l’arbitro della partita, di cui si conoscono i soli dati anagrafici, i calciatori<br />

della prima squadra ed i calciatori della seconda. Infine, per ciascun calciatore, sia esso della prima o<br />

della seconda squadra, è necessario tener traccia del ruolo e dell’eventuale numero di reti segnato in<br />

ogni partita e di un campo che indichi se il calciatore giochi come capitano in ciascuna delle partite<br />

disputate.<br />

Indicare le cardinalità delle relazioni e un identificatore per ciascuna entità.


N.B. era possibile anche considerare l’entità FUN CLUB come entità debole dall’entità CALCIATORE<br />

senza chiave parziale<br />

Business rules:<br />

1) punt_parziale e punt_finale devono essere stringhe di testo di questo tipo ‘_:_’<br />

2) serie può assumere i valori ‘A’ oppure ‘B’;<br />

3) capitano può assumere solo due valori (vero/falso oppure sì/no)<br />

4) il codice dello stadio è alfanumerico


<strong>Esercizi</strong>o b<br />

Si definiscano le relazioni (tabelle) risultanti in SQL, avendo cura di esplicitare i vincoli di integrità.<br />

Si riportano per brevità la definizione SQL solamente delle seguenti tabelle: FUN CLUB, PARTITA e<br />

GIOCA_CASA<br />

CREATE TABLE FUN CLUB<br />

(<br />

URL char(30) primary key,<br />

N_tessera char(8) references GIOCATORE (N_tessera),<br />

data_creazione date,<br />

N_iscritti int,<br />

quota_iscrizione numeric(6,2)<br />

)<br />

CREATE TABLE PARTITA<br />

(<br />

data date,<br />

codStadio char(8) references STADIO (codice),<br />

ora_in time,<br />

ora_fin time,<br />

punt_parziale char(3) check( punt_parziale LIKE ‘_:_’),<br />

punt_finale char(3) check( punt_finale LIKE ‘_:_’),<br />

serie char(1) check( serie IN (‘A’,’B’)),<br />

CFarbitro char(16) references ARBITRO (CF),<br />

squadra_ospite int references SQUADRA (codice),<br />

squadra_casa int references SQUADRA (codice),<br />

primary key (data, codStadio)<br />

)<br />

CREATE TABLE GIOCA_CASA<br />

(<br />

N_tessera char(8) references CALCIATORE (N_tessera),<br />

data date,<br />

codStadio char(8),<br />

ruolo varchar(30),<br />

capitano bit,<br />

N_reti,<br />

primary key (N_tessera, data, codStadio)<br />

foreign key(data, codStadio) references PARTITA(data, codStadio)<br />

)


<strong>Esercizi</strong>o c<br />

Si vuole realizzare un database relativo alla gestione delle consegne di una società di trasporti. E’ stata a<br />

tal fine costruita, da un inesperto progettista, un’unica tabella descritta dai seguenti attributi:<br />

(Targa_mezzo, data_immatricolazione, modello, N_patente, nome, cognome, data_nascita,<br />

livello_servizio, data_consegna, N_ord_consegna, N_colli_consegnati, PIVA_dettagliante,<br />

ragione_sociale, via, civico, città, provincia)<br />

Nell’ipotesi che un dettagliante possa ricevere una sola consegna al giorno e che l’attributo<br />

N_ord_consegna indica il numero progressivo assegnato a ciascun dettagliante/consegna per<br />

definire l’ordine delle consegne, se ne determini la chiave e si individuino, esplicitandole, le dipendenze<br />

funzionali. Sulla base di queste si proceda alla normalizzazione in 3° forma normale, preservando le dip.<br />

Funzionali.<br />

IPOTESI 1 - dettagliante possa ricevere una sola consegna al giorno<br />

IPOTESI 2 - N_ord_consegna indica il numero progressivo assegnato a ciascun<br />

dettagliante/consegna per definire l’ordine delle consegne<br />

(1) Targa_mezzo data_immatricolazione, modello<br />

(2) N_patente nome, cognome, data_nascita, livello_servizio<br />

Si osservi che il livello di servizio poteva anche essere associato ad ogni consegna piuttosto che al<br />

conducente<br />

(3) PIVA_dettagliante ragione_sociale, via, civico, città<br />

(4) Città provincia (nell’ipotesi che fissata la città determino univocamente la provincia)<br />

Per le ipotesi della traccia posso identificare univocamente una consegna con data_consegna e<br />

piva_dettagliante (IPOTESI 1) oppure con data_consegna e N_ord_consegna (IPOTESI 2).<br />

In particolare se fisso (soluzione A)<br />

(Data_consegna, piva_dettagliante) determino univocamente il numero d’ordine della relativa consegna<br />

(in termini di dipendenze funzionali avrò Data_consegna, piva_dettagliante N_ord_consegna)<br />

mentre se fisso (soluzione B)<br />

(Data_consegna, N_ord_consegna) determino univocamente la piva_dettagliante associata alla relativa<br />

consegna (in termini di dipendenze funzionali avrò Data_consegna, N_ord_consegna <br />

piva_dettagliante)<br />

In accordo alla soluzione A ottengo la seguente dipendenza funzionale<br />

(5) Data_consegna, piva_dettagliante N_ord_consegna, N_colli_consegnati, targa_mezzo, N_patente


La chiave della tabella risulta essere in questo caso (soluzione A): Data_consegna, piva_dettagliante<br />

Infine, si poteva anche ipotizzare che il numero d’ordine delle consegne fosse sempre lo stesso e non<br />

venisse calcolato di giorno in giorno. In questo caso l’attributo N_ord_consegna andava associato<br />

direttamente alla piva_dettagliante (PIVA_dettagliante ragione_sociale, via, civico, città,<br />

N_ord_consegna) e l’unica chiave possibile per la tabella diventava quella in accordo alla soluzione A<br />

<strong>Esercizi</strong>o d<br />

Date le seguenti relazioni:<br />

CLIENTE (CodCliente, nome, cognome, gg_nascita, mm_nascita, aa_nascita)<br />

PRODOTTO (CodProdotto, nome)<br />

ACQUISTO (CodAcquisto, gg_acquisto, mm_acquisto, aa_acquisto, ora_acquisto, CodCliente)<br />

PRODOTTI_ACQUISTATI(CodAcquisto, CodProdotto, Num_pezzi)<br />

esprimere in SQL le seguenti interrogazioni:<br />

1) Estrarre in ordine alfabetico i dati dei clienti che hanno fatto un acquisto il giorno del loro<br />

compleanno.<br />

SELECT distinct Cliente.*<br />

FROM Cliente natural join Acquisto<br />

WHERE gg_nascita=gg_acquisto<br />

AND mm_nascita=mm_acquisto<br />

ORDER BY cognome, nome<br />

Oppure<br />

SELECT *<br />

FROM Cliente C<br />

WHERE codCliente IN ( SELECT distinct codCliente<br />

FROM Acquisto<br />

WHERE mm_acquisto = C.gg_nascita<br />

AND mm_acquisto = C.mm_nascita)<br />

ORDER BY cognome, nome<br />

Oppure<br />

SELECT *<br />

FROM Cliente C<br />

WHERE (gg_nascita, mm_nascita) IN ( SELECT gg_acquisto, mm_acquisto<br />

FROM Acquisto<br />

WHERE codCliente = C.codCliente<br />

)<br />

ORDER BY cognome, nome


2) Selezionare i prodotti per i quali nel 2007 è stato venduto un numero di pezzi complessivo superiore a<br />

4000.<br />

SELECT *<br />

FROM Prodotto<br />

WHERE codProdotto IN ( SELECT codProdotto<br />

FROM Acquisto natural join Prodotti_acquistati<br />

WHERE aa_acquisto = 2007<br />

GROUP BY codProdotto<br />

HAVING sum(Num_pezzi) > 4000)<br />

Esempi di Normalizzazione<br />

1) Appello 7 Aprile 2006<br />

Si vuole realizzare un database relativo alla gestione delle chiamate di assistenza di un call center.<br />

E’ stata a tal fine costruita, da un inesperto progettista, un’unica tabella descritta dai seguenti attributi:<br />

(cod_operatore, nome, cognome, tipo_operatore, data_chiamata, ora_inizio, ora_fine, CF_cliente,<br />

nome, cognome, data_nascita, tipo_pagamento_assistenza, cod_assistenza,<br />

descrizione_cod_assistenza, costo_assistenza_chiamata)<br />

Ipotesi della traccia: ciascuna chiamata può soddisfare più problemi di assistenza<br />

1. cod_operatore → nome, cognome, tipo_operatore<br />

2. CF_cliente → nome, cognome, data_nascita<br />

3. cod_assistenza → descrizione_cod_assistenza<br />

Osservazione: Un operatore in un certo istante prenderà una sola chiamata e quindi fissati operatore,<br />

data ed ora risultano univocamente definiti anche il cliente che effettua la chiamata e l’ora di fine della<br />

stessa<br />

4. cod_operatore, data_chiamata, ora_inizio → ora_fine, CF_cliente<br />

Osservazione: secondo quanto indicato dalla traccia una stessa chiamata può risolvere più problemi di<br />

assistenza ossia fissata la chiamata è possibile avere N codici di assistenza diversi ed analogamente<br />

fissato un codice di assistenza questo può riferirsi ad N chiamate diverse pertanto si ottiene la seguente<br />

ultima dipendenza<br />

5. cod_operatore, data_chiamata, ora_inizio, cod_assistenza → tipo_pagamento,<br />

costo_assistenza_chiamata


Osservazione: Si è considerato il caso più generale in cui il costo_assistenza_chiamata sia il costo<br />

associato ad un problema di assistenza risolto durante una particolare chiamata<br />

Chiave della tabella: cod_operatore, data_chiamata, ora_inizio, cod_assistenza<br />

• dipendenza piena (la dip. 5);<br />

• dipendenza parziale (la dip. 1, 3, 4 );<br />

• dipendenza transitiva (la dip. 2).


2) Appello 23 Giugno 2006<br />

Si vuole realizzare un database relativo alla gestione delle valutazioni delle prove di un concorso. E’<br />

stata a tal fine costruita, da un inesperto progettista, un’unica tabella descritta dai seguenti attributi:<br />

(CF_partecipante, nome_p, cognome_p, data_nascita, laurea, num_titoli, CF_commissario, nome_c,<br />

cognome_c, titolo_c, codice_elaborato, ora_consegna, num_pagine, puntegg_elaborato,<br />

data_valutazione, ora_valutazione, punteggio_commissario)<br />

Ipotesi della traccia: ciascun elaborato è valutato da più commissari<br />

1. CF_partecipante → nome_p, cognome_p, data_nascita, laurea, num_titoli, codice_elaborato<br />

2. CF_commissario → nome_c, cognome_c, titolo_c<br />

3. codice_elaborato → ora_consegna, num_pagine, puntegg_elaborato<br />

Osservazione: consideriamo l’ipotesi della traccia ed il fatto che è plausibile supporre che un<br />

commissario valuti un elaborato una sola volta e che tale valutazione avverrà in una certa data ed ora<br />

4. CF_partecipante, CF_commissario → punteggio_commissario, data_valutazione, ora_valutazione<br />

Chiave della tabella: CF_partecipante, CF_commissario<br />

• dipendenza piena (la dip. 4);<br />

• dipendenza parziale (la dip. 1, 2 );<br />

• dipendenza transitiva (la dip. 3).


3) Appello 28 Settembre 2006<br />

Si vuole realizzare un database relativo alla gestione dei contratti di affitto dei posti auto di un<br />

autosilo. E’ stata a tal fine costruita, da un inesperto progettista, un’unica tabella descritta dai seguenti<br />

attributi:<br />

(N_patente, data_rilascio, nome, cognome, cellulare, N_targa, modello, colore,<br />

anno_immatricolazione, stato_auto, num_piano, num_box, data_inizio_contratto, data_fine_contratto,<br />

prezzo_affitto)<br />

1. N_patente → data_rilascio, nome, cognome, cellulare<br />

2. N_targa → modello, colore, anno_immatricolazione<br />

3. num_box → num_piano<br />

4. N_targa, data_inizio_contratto → data_fine_contratto, prezzo_affitto, N_patente, num_box,<br />

stato_auto<br />

Osservazione: Si è considerato il caso più generale in cui il proprietario varia nel tempo altrimenti si<br />

poteva anche far dipendere N_patente da N_targa<br />

Chiave della tabella: N_targa, data_inizio_contratto<br />

• dipendenza piena (la dip. 4);<br />

• dipendenza parziale (la dip. 2);<br />

• dipendenza transitiva (la dip. 1,3).


ESEMPI di query SQL<br />

1) Appello 21 Novembre 2006<br />

d) Date le seguenti relazioni:<br />

CONTROLLORE (CF, nome, cognome, data_nascita, codice)<br />

CONTROLLO_AZIENDA (data_controllo, CF_controllore, ora, azienda_riferimento)<br />

RISULTATI_ANALISI_BOVINO ((Data_controllo, CF_controllore, ID_bovino, proteine, lattosio, grasso)<br />

esprimere in SQL le seguenti interrogazioni:<br />

1) Estrarre i dati relativi a 2 controlli: il primo è quello in data odierna ed il secondo è quello<br />

immediatamente precedente.<br />

I soluzione che considera un ordine temporale basato solo sulla data<br />

SELECT *<br />

FROM controllo_azienda<br />

WHERE data_controllo = '21-11-2006'<br />

OR data_controllo = (SELECT max(data_controllo)<br />

FROM controllo_azienda<br />

WHERE data_controllo < '21-11-2006')<br />

II soluzione che considera un ordine temporale basato sulla data e sull’ora<br />

select *<br />

from controllo_azienda<br />

where data_controllo = '21-11-2006'<br />

AND ora=(select max(ora)<br />

from controllo_azienda<br />

where data_controllo = '21-11-2006')<br />

UNION<br />

select *<br />

from controllo_azienda<br />

where (data_controllo, ora) = (select max(data_controllo),max(ora)<br />

from controllo_azienda<br />

where (data_controllo = '21-11-2006'<br />

AND ora1 < (select ora<br />

from controllo_azienda<br />

where (data_controllo, ora) = (select max(data_controllo), max(ora)<br />

from controllo_azienda<br />

where data_controllo = '21-11-2006')))<br />

OR<br />

(data_controllo = (select max(data_controllo)<br />

from controllo_azienda<br />

where data_controllo < '21-11-2006'))<br />

)


2) Estrarre i controllori che hanno partecipato a controlli per cui si è avuto un valor medio in grasso<br />

pari a 4.5 ed un valor medio in proteine superiore a 4.<br />

SELECT *<br />

FROM controllore<br />

Where CF IN (SELECT distinct CF_controllore<br />

FROM risultati_analisi_bovino<br />

GROUP BY data_controllo, CF_controllore<br />

HAVING avg(grasso) = 4.5 AND avg (proteine) > 4)<br />

2) Appello 28 Settembre 2006<br />

d) Date le seguenti relazioni:<br />

GIOCATORE (N_tessera, nome, cognome, data_nascita, squadra_attuale)<br />

PARTITA (Codice, squadra1, squadra2, campionato, punteggio1, punteggio2)<br />

GIOCATA (Codice, N_tessera, num_reti)<br />

esprimere in SQL la seguente interrogazione:<br />

1) Estrarre i dati del capocannoniere del campionato 2004/2005.<br />

SELECT *<br />

FROM giocatore<br />

WHERE N_tessera IN ( SELECT N_tessera<br />

FROM partita NATURAL JOIN giocata<br />

WHERE campionato = '2004-2005'<br />

GROUP BY N_tessera<br />

HAVING sum(num_reti) >= ALL (SELECT sum(num_reti)<br />

FROM partita NATURAL JOIN giocata<br />

WHERE campionato = '2004-2005'<br />

GROUP BY N_tessera))


3) Appello 24 Settembre 2005 ed Esempi vari<br />

Date le seguenti relazioni:<br />

GUIDATORE ( CF, nome, cognome, età, N_patente)<br />

AUTO ( Targa, data_immatricolazione, modello, CF_guidatore)<br />

INCIDENTE ( Codice, anno, data_ora_riferimento, indirizzo, num_auto_coinvolte, num_feriti)<br />

AUTO_INCIDENTE ( Codice, anno, targa)<br />

esprimere in SQL le seguenti interrogazioni:<br />

1) Selezionare, per ciascun incidente, l’età media dei guidatori coinvolti.<br />

SELECT Codice,anno,avg(eta)<br />

FROM guidatore,auto,auto_incidente<br />

WHERE CF=CF_guidatore AND auto.Targa=auto_incidente.targa<br />

GROUP BY Codice,anno;<br />

2) Selezionare il numero di auto coinvolte ed il numero di feriti del primo e dell’ultimo incidente (su<br />

base temporale) memorizzati nella base di dati .<br />

SELECT num_auto_coinvolte, num_feriti, data_ora_riferimento<br />

FROM incidente<br />

WHERE data_ora_riferimento = (select max(data_ora_riferimento) from incidente)<br />

OR data_ora_riferimento = (select min(data_ora_riferimento) from incidente)<br />

Oppure<br />

SELECT num_auto_coinvolte, num_feriti<br />

FROM incidente<br />

WHERE data_ora_riferimento >= ALL (select data_ora_riferimento from incidente)<br />

OR data_ora_riferimento = ALL (SELECT count(*)<br />

FROM guidatore,auto,auto_incidente<br />

WHERE CF=CF_guidatore AND auto.Targa=auto_incidente.targa<br />

GROUP BY CF);


4) Mostrare i guidatori che non sono mai stati coinvolti in incidenti.<br />

SELECT *<br />

FROM guidatore<br />

WHERE CF NOT IN (SELECT distinct CF_guidatore<br />

FROM auto natural join auto_incidente)<br />

5) Selezionare le auto e l’età del relativo guidatore che non hanno fatto più di due incidenti.<br />

SELECT Targa, modello, eta<br />

FROM guidatore,auto<br />

WHERE CF=CF_guidatore AND targa IN (SELECT targa<br />

FROM auto_incidente<br />

GROUP BY targa<br />

HAVING count(*)

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!