Il 0% ha trovato utile questo documento (0 voti)
7K visualizzazioni71 pagine

SQL - Group by Having

Esercizi SQL svolti e commentati con clausole GROUP BY e HAVING. Sono discussi anche alcuni errori tipici.

Caricato da

Cinzia Bocchi
Copyright
© Attribution Non-Commercial ShareAlike (BY-NC-SA)
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
7K visualizzazioni71 pagine

SQL - Group by Having

Esercizi SQL svolti e commentati con clausole GROUP BY e HAVING. Sono discussi anche alcuni errori tipici.

Caricato da

Cinzia Bocchi
Copyright
© Attribution Non-Commercial ShareAlike (BY-NC-SA)
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 71

Bocchi Cinzia 03/01/2015

Correzione verifica di Informatica: SQL e GROUP BY HAVING

INDICE

Lo schema relazionale
Le tabelle di esempio
Le query richieste
Query 1: soluzione proposta
Query 2: soluzione proposta
Prima alternativa corretta
Seconda alternativa corretta
Terza alternativa corretta
Quarta alternativa corretta
Quinta alternativa corretta
Alternativa corretta solo in mancanza di hotel omonimi
Alternativa analoga alla seconda ma non ottimizzata
Alternativa analoga alla quarta ma non ottimizzata
Alternativa errata
Query 3: soluzione proposta
Prima alternativa corretta
Seconda alternativa corretta
Alternativa corretta solo in mancanza di hotel omonimi
Alternativa analoga alla seconda ma non ottimizzata
Alternativa incompleta
Alternativa errata
Query 4: soluzione proposta
Prima alternativa corretta
Seconda alternativa corretta
Alternativa corretta solo in mancanza di hotel omonimi
Alternativa analoga alla seconda ma non ottimizzata
Prima alternativa errata
Seconda alternativa errata
Query 5: soluzione proposta
Alternativa non ottimizzata
Alternativa errata
Query 6: soluzione proposta
Prima alternativa errata
Seconda alternativa errata
Terza alternativa errata
Quarta alternativa errata
Quinta alternativa errata
Query 7: soluzione proposta
Prima alternativa non ottimizzata
Seconda alternativa non ottimizzata
Query 8: soluzione proposta
Alternativa corretta solo in mancanza di hotel omonimi
Alternativa non ottimizzata
Prima alternativa errata
Seconda alternativa errata

1
Bocchi Cinzia 03/01/2015

LO SCHEMA RELAZIONALE

hotel (codHotel, nome, citta)

stanza (numStanza, codHotel, tipo, prezzo, occupata)

prenotazione (numStanza, codHotel, idCliente, dataInizio, dataFine)

cliente (idCliente, nome, citta)

torna all’indice

2
Bocchi Cinzia 03/01/2015

LE TABELLE DI ESEMPIO

hotel
codHotel nome citta
100 Miramare Rimini
110 Marittimo Rimini
120 La baita Aosta
130 Miramare Napoli
140 Fiesta Rimini
150 Fiesta Torino

stanza
numStanza codHotel tipo prezzo occupata
1 100 singola 60,00 1
2 100 doppia 58,00 1
3 100 singola 65,00 0
4 100 doppia 61,00 1
1 110 singola 60,00 1
2 110 doppia 80,00 0
3 110 singola 95,00 0
1 120 singola 100,00 1
2 120 doppia 95,00 0
3 120 singola 150,00 0
4 120 singola 200,00 1
21 130 doppia 250,00 0
22 130 singola 300,00 0
25 130 singola 150,00 0
55 140 doppia 99,00 1
58 140 singola 100,00 1
1 150 doppia 250,00 0
2 150 singola 180,00 0
3 150 singola 150,00 0
4 150 doppia 250,00 1
5 150 singola 160,00 1
6 150 doppia 350,00 1
7 150 singola 100,00 1

 Il prezzo di una stanza è riferito ad una notte di pernottamento


 L’attributo occupata assume valore 1 se la stanza è occupata, 0 altrimenti

3
Bocchi Cinzia 03/01/2015

cliente
idCliente nome città
1 Rossi Torino
2 Neri Milano
3 Verdi Roma
4 Rossi Catania
5 Verdi Roma
6 Bianchi Roma
7 Marrone Roma

prenotazione
numStanza codHotel idCliente data Inizio dataFine
1 100 2 2013-07-14 2013-07-20
1 100 4 2013-08-10 2013-08-20
2 110 1 2013-07-02 2013-07-09
55 140 3 2013-08-20 2013-08-28
3 100 4 2013-09-01 2013-09-18
55 140 5 2013-09-12 2013-09-30
58 140 6 2013-07-01 2013-07-15
4 120 7 2014-05-10 2014-05-20
22 130 1 2014-06-05 2014-06-15
4 150 3 2015-03-01
5 150 4 2015-03-15
1 120 2 2015-05-20
1 150 3 2015-07-12
2 150 5 2015-07-20
3 150 6 2015-07-15
1 100 7 2015-07-13
3 100 4 2015-07-19
3 110 2 2015-07-11

 L’attributo dataFine è opzionale, cioè può non essere specificato

torna all’indice

4
Bocchi Cinzia 03/01/2015

LE QUERY RICHIESTE

1) Per ogni città trovare il numero di hotel


2) Per ogni hotel trovare il numero di stanze occupate
3) Per ogni hotel trovare il prezzo minimo e massimo delle stanze, indipendentemente
dalla tipologia
4) Per ogni hotel trovare il prezzo minimo e massimo delle stanze singole
5) Per ogni cliente (è sufficiente l’idCliente), trovare il numero di prenotazioni effettuate in
hotel di Rimini nell’anno 2013 (si consideri solo dataInizio)
6) Trovare il prezzo medio delle stanze, suddivise per tipologia, ma solo se il numero di
stanze per tipologia è superiore a 100
7) Per ogni hotel (è sufficiente conoscere il codHotel) determinare il numero di
prenotazioni effettuate prima del 10-07-2015 (si utilizzi dataInizio), unicamente nel caso
tale numero sia superiore a 10
8) Per ogni città e per ogni hotel operante in tale città determinare il numero di
prenotazioni effettuate nel periodo 10-07-2015 e 20-07-2015 (si utilizzi dataInizio) da
clienti provenienti da Roma

torna all’indice

5
Bocchi Cinzia 03/01/2015

1) Per ogni città trovare il numero di hotel

SELECT H.citta, COUNT(*) AS NumeroHotel


FROM hotel H
GROUP BY H.citta

passo 1  Sulla tabella hotel viene effettuato un raggruppamento in base al campo citta.

codHotel nome citta


100 Miramare Rimini
110 Marittimo Rimini gruppo 1 città Rimini
140 Fiesta Rimini
120 La baita Aosta gruppo 2 città Aosta

130 Miramare Napoli gruppo 3 città Napoli

150 Fiesta Torino gruppo 4 città Torino

passo 2  Viene eseguita la funzione count presente in select per ogni gruppo.

codHotel nome citta


100 Miramare Rimini
110 Marittimo Rimini gruppo 1 città Rimini count=3
140 Fiesta Rimini

120 La baita Aosta gruppo 2 città Aosta count=1

130 Miramare Napoli gruppo 3 città Napoli count=1

150 Fiesta Torino gruppo 4 città Torino count=1

passo 3  Viene effettuata la proiezione sui campi della select.

citta NumeroHotel
Rimini 3
Aosta 1
Napoli 1
Torino 1

torna all’indice
6
Bocchi Cinzia 03/01/2015

2) Per ogni hotel trovare il numero di stanze occupate

SELECT H.codHotel, H.nome, COUNT(*) AS NumStanzeOccupate


FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel AND S.occupata = 1
GROUP BY H.codHotel, H.nome

passo 1  Viene eseguito il prodotto cartesiano delle tabelle presenti in from: ogni riga
della tabella hotel viene combinata con tutte le righe della tabella stanza.

codHotel nome citta numStanza codHotel tipo prezzo occupata


100 Miramare Rimini 1 100 singola 60,00 1
100 Miramare Rimini 2 100 doppia 58,00 1
100 Miramare Rimini 3 100 singola 65,00 0
100 Miramare Rimini 4 100 doppia 61,00 1
100 Miramare Rimini 1 110 singola 60,00 1
100 Miramare Rimini 2 110 doppia 80,00 0
100 Miramare Rimini 3 110 singola 95,00 0
100 Miramare Rimini 1 120 singola 100,00 1
100 Miramare Rimini 2 120 doppia 95,00 0
100 Miramare Rimini 3 120 singola 150,00 0
100 Miramare Rimini 4 120 singola 200,00 1
100 Miramare Rimini 21 130 doppia 250,00 0
100 Miramare Rimini 22 130 singola 300,00 0
100 Miramare Rimini 25 130 singola 150,00 0
100 Miramare Rimini 55 140 doppia 99,00 1
100 Miramare Rimini 58 140 singola 100,00 1
100 Miramare Rimini 1 150 doppia 250,00 0
100 Miramare Rimini 2 150 singola 180,00 0
100 Miramare Rimini 3 150 singola 150,00 0
100 Miramare Rimini 4 150 doppia 250,00 1
100 Miramare Rimini 5 150 singola 160,00 1
100 Miramare Rimini 6 150 doppia 350,00 1
100 Miramare Rimini 7 150 singola 100,00 1
110 Marittimo Rimini 1 100 singola 60,00 1
110 Marittimo Rimini 2 100 doppia 58,00 1
110 Marittimo Rimini 3 100 singola 65,00 0
110 Marittimo Rimini 4 100 doppia 61,00 1
110 Marittimo Rimini 1 110 singola 60,00 1
110 Marittimo Rimini 2 110 doppia 80,00 0
110 Marittimo Rimini 3 110 singola 95,00 0
110 Marittimo Rimini 1 120 singola 100,00 1
110 Marittimo Rimini 2 120 doppia 95,00 0
110 Marittimo Rimini 3 120 singola 150,00 0
110 Marittimo Rimini 4 120 singola 200,00 1
110 Marittimo Rimini 21 130 doppia 250,00 0

7
Bocchi Cinzia 03/01/2015

110 Marittimo Rimini 22 130 singola 300,00 0


110 Marittimo Rimini 25 130 singola 150,00 0
110 Marittimo Rimini 55 140 doppia 99,00 1
110 Marittimo Rimini 58 140 singola 100,00 1
110 Marittimo Rimini 1 150 doppia 250,00 0
110 Marittimo Rimini 2 150 singola 180,00 0
110 Marittimo Rimini 3 150 singola 150,00 0
110 Marittimo Rimini 4 150 doppia 250,00 1
110 Marittimo Rimini 5 150 singola 160,00 1
110 Marittimo Rimini 6 150 doppia 350,00 1
110 Marittimo Rimini 7 150 singola 100,00 1
120 La baita Aosta 1 100 singola 60,00 1
120 La baita Aosta 2 100 doppia 58,00 1
120 La baita Aosta 3 100 singola 65,00 0
120 La baita Aosta 4 100 doppia 61,00 1
120 La baita Aosta 1 110 singola 60,00 1
120 La baita Aosta 2 110 doppia 80,00 0
120 La baita Aosta 3 110 singola 95,00 0
120 La baita Aosta 1 120 singola 100,00 1
120 La baita Aosta 2 120 doppia 95,00 0
120 La baita Aosta 3 120 singola 150,00 0
120 La baita Aosta 4 120 singola 200,00 1
120 La baita Aosta 21 130 doppia 250,00 0
120 La baita Aosta 22 130 singola 300,00 0
120 La baita Aosta 25 130 singola 150,00 0
120 La baita Aosta 55 140 doppia 99,00 1
120 La baita Aosta 58 140 singola 100,00 1
120 La baita Aosta 1 150 doppia 250,00 0
120 La baita Aosta 2 150 singola 180,00 0
120 La baita Aosta 3 150 singola 150,00 0
120 La baita Aosta 4 150 doppia 250,00 1
120 La baita Aosta 5 150 singola 160,00 1
120 La baita Aosta 6 150 doppia 350,00 1
120 La baita Aosta 7 150 singola 100,00 1
130 Miramare Napoli 1 100 singola 60,00 1
130 Miramare Napoli 2 100 doppia 58,00 1
130 Miramare Napoli 3 100 singola 65,00 0
130 Miramare Napoli 4 100 doppia 61,00 1
130 Miramare Napoli 1 110 singola 60,00 1
130 Miramare Napoli 2 110 doppia 80,00 0
130 Miramare Napoli 3 110 singola 95,00 0
130 Miramare Napoli 1 120 singola 100,00 1
130 Miramare Napoli 2 120 doppia 95,00 0
130 Miramare Napoli 3 120 singola 150,00 0
130 Miramare Napoli 4 120 singola 200,00 1
130 Miramare Napoli 21 130 doppia 250,00 0
130 Miramare Napoli 22 130 singola 300,00 0
130 Miramare Napoli 25 130 singola 150,00 0
130 Miramare Napoli 55 140 doppia 99,00 1
8
Bocchi Cinzia 03/01/2015

130 Miramare Napoli 58 140 singola 100,00 1


130 Miramare Napoli 1 150 doppia 250,00 0
130 Miramare Napoli 2 150 singola 180,00 0
130 Miramare Napoli 3 150 singola 150,00 0
130 Miramare Napoli 4 150 doppia 250,00 1
130 Miramare Napoli 5 150 singola 160,00 1
130 Miramare Napoli 6 150 doppia 350,00 1
130 Miramare Napoli 7 150 singola 100,00 1
140 Fiesta Rimini 1 100 singola 60,00 1
140 Fiesta Rimini 2 100 doppia 58,00 1
140 Fiesta Rimini 3 100 singola 65,00 0
140 Fiesta Rimini 4 100 doppia 61,00 1
140 Fiesta Rimini 1 110 singola 60,00 1
140 Fiesta Rimini 2 110 doppia 80,00 0
140 Fiesta Rimini 3 110 singola 95,00 0
140 Fiesta Rimini 1 120 singola 100,00 1
140 Fiesta Rimini 2 120 doppia 95,00 0
140 Fiesta Rimini 3 120 singola 150,00 0
140 Fiesta Rimini 4 120 singola 200,00 1
140 Fiesta Rimini 21 130 doppia 250,00 0
140 Fiesta Rimini 22 130 singola 300,00 0
140 Fiesta Rimini 25 130 singola 150,00 0
140 Fiesta Rimini 55 140 doppia 99,00 1
140 Fiesta Rimini 58 140 singola 100,00 1
140 Fiesta Rimini 1 150 doppia 250,00 0
140 Fiesta Rimini 2 150 singola 180,00 0
140 Fiesta Rimini 3 150 singola 150,00 0
140 Fiesta Rimini 4 150 doppia 250,00 1
140 Fiesta Rimini 5 150 singola 160,00 1
140 Fiesta Rimini 6 150 doppia 350,00 1
140 Fiesta Rimini 7 150 singola 100,00 1
150 Fiesta Torino 1 100 singola 60,00 1
150 Fiesta Torino 2 100 doppia 58,00 1
150 Fiesta Torino 3 100 singola 65,00 0
150 Fiesta Torino 4 100 doppia 61,00 1
150 Fiesta Torino 1 110 singola 60,00 1
150 Fiesta Torino 2 110 doppia 80,00 0
150 Fiesta Torino 3 110 singola 95,00 0
150 Fiesta Torino 1 120 singola 100,00 1
150 Fiesta Torino 2 120 doppia 95,00 0
150 Fiesta Torino 3 120 singola 150,00 0
150 Fiesta Torino 4 120 singola 200,00 1
150 Fiesta Torino 21 130 doppia 250,00 0
150 Fiesta Torino 22 130 singola 300,00 0
150 Fiesta Torino 25 130 singola 150,00 0
150 Fiesta Torino 55 140 doppia 99,00 1
150 Fiesta Torino 58 140 singola 100,00 1
150 Fiesta Torino 1 150 doppia 250,00 0
150 Fiesta Torino 2 150 singola 180,00 0
9
Bocchi Cinzia 03/01/2015

150 Fiesta Torino 3 150 singola 150,00 0


150 Fiesta Torino 4 150 doppia 250,00 1
150 Fiesta Torino 5 150 singola 160,00 1
150 Fiesta Torino 6 150 doppia 350,00 1
150 Fiesta Torino 7 150 singola 100,00 1

passo 2  Viene applicata la condizione di equi join H.codHotel = S.codHotel che


consente di mantenere solo le righe formate da record tra loro correlati (vedere le colonne
con sfondo grigio nella precedente tabella); le righe che non soddisfano tale condizione
vengono eliminate.

codHotel nome citta numStanza codHotel tipo prezzo occupata


100 Miramare Rimini 1 100 singola 60,00 1
100 Miramare Rimini 2 100 doppia 58,00 1
100 Miramare Rimini 3 100 singola 65,00 0
100 Miramare Rimini 4 100 doppia 61,00 1
110 Marittimo Rimini 1 110 singola 60,00 1
110 Marittimo Rimini 2 110 doppia 80,00 0
110 Marittimo Rimini 3 110 singola 95,00 0
120 La baita Aosta 1 120 singola 100,00 1
120 La baita Aosta 2 120 doppia 95,00 0
120 La baita Aosta 3 120 singola 150,00 0
120 La baita Aosta 4 120 singola 200,00 1
130 Miramare Napoli 21 130 doppia 250,00 0
130 Miramare Napoli 22 130 singola 300,00 0
130 Miramare Napoli 25 130 singola 150,00 0
140 Fiesta Rimini 55 140 doppia 99,00 1
140 Fiesta Rimini 58 140 singola 100,00 1
150 Fiesta Torino 1 150 doppia 250,00 0
150 Fiesta Torino 2 150 singola 180,00 0
150 Fiesta Torino 3 150 singola 150,00 0
150 Fiesta Torino 4 150 doppia 250,00 1
150 Fiesta Torino 5 150 singola 160,00 1
150 Fiesta Torino 6 150 doppia 350,00 1
150 Fiesta Torino 7 150 singola 100,00 1

passo 3  Viene applicata l’ulteriore condizione presente in where: S.occupata = 1


(vedere la colonna con sfondo grigio nella tabella precedente); tutte le righe che non
soddisfano tale condizione vengono eliminate.

codHotel nome citta numStanza codHotel tipo prezzo occupata


100 Miramare Rimini 1 100 singola 60,00 1
100 Miramare Rimini 2 100 doppia 58,00 1
100 Miramare Rimini 4 100 doppia 61,00 1
110 Marittimo Rimini 1 110 singola 60,00 1
120 La baita Aosta 1 120 singola 100,00 1
120 La baita Aosta 4 120 singola 200,00 1

10
Bocchi Cinzia 03/01/2015

140 Fiesta Rimini 55 140 doppia 99,00 1


140 Fiesta Rimini 58 140 singola 100,00 1
150 Fiesta Torino 4 150 doppia 250,00 1
150 Fiesta Torino 5 150 singola 160,00 1
150 Fiesta Torino 6 150 doppia 350,00 1
150 Fiesta Torino 7 150 singola 100,00 1

passo 4  Viene effettuato il raggruppamento sui campi codHotel e nome della tabella
hotel (vedere i nomi colonne evidenziati in giallo).

codHotel nome ... ...


100 Miramare ... ...
gruppo 1: 100 Miramare
100 Miramare ... ...
100 Miramare ... ...
gruppo 2: 110 Marittimo
110 Marittimo ... ...

120 La baita ... ... gruppo 3: 120 La baita


120 La baita ... ...
140 Fiesta ... ... gruppo 4: 140 Fiesta
140 Fiesta ... ...
150 Fiesta ... ...
150 Fiesta ... ...
gruppo 5: 150 Fiesta
150 Fiesta ... ...
150 Fiesta ... ...

passo 5  Viene eseguita la funzione count presente in select, su ciascun gruppo.

codHotel nome ... ...


100 Miramare ... ...
100 Miramare ... ... gruppo 1: 100 Miramare count=3
100 Miramare ... ...

110 Marittimo ... ... gruppo 2: 110 Marittimo count=1

120 La baita ... ...


gruppo 3: 120 La baita count=2
120 La baita ... ...
140 Fiesta ... ...
gruppo 4: 140 Fiesta count=2
140 Fiesta ... ...
150 Fiesta ... ...
150 Fiesta ... ...
150 Fiesta ... ... gruppo 5: 150 Fiesta count=4
150 Fiesta ... ...

11
Bocchi Cinzia 03/01/2015

passo 6  Viene effettuata la proiezione sui campi della select.

codHotel nome NumStanzeOccupate


100 Miramare 3
110 Marittimo 1
120 La baita 2
140 Fiesta 2
150 Fiesta 4

Come si può notare, il codice dell’hotel consente di distinguere tra hotel che hanno lo
stesso nome.

torna all’indice

Prima alternativa corretta

SELECT H.nome, COUNT(*) AS NumStanzeOccupate


FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel AND S.occupata = 1
GROUP BY H.codHotel, H.nome

In tal caso il resultset non presenta la colonna codHotel, ma gli hotel con lo stesso nome e
codice diverso non vengono raggruppati.

nome NumStanzeOccupate
Miramare 3
Marittimo 1
La baita 2
Fiesta 2
Fiesta 4

torna all’indice

12
Bocchi Cinzia 03/01/2015

Seconda alternativa corretta

SELECT S.codHotel, COUNT(*) AS NumStanzeOccupate


FROM stanza S
WHERE S.occupata = 1
GROUP BY S.codHotel

passo 1  Viene applicata la condizione presente in where alla tabella stanza: tutte le
righe che non soddisfano la condizione S.occupata = 1 vengono eliminate.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
2 100 doppia 58,00 1
4 100 doppia 61,00 1
1 110 singola 60,00 1
1 120 singola 100,00 1
4 120 singola 200,00 1
55 140 doppia 99,00 1
58 140 singola 100,00 1
4 150 doppia 250,00 1
5 150 singola 160,00 1
6 150 doppia 350,00 1
7 150 singola 100,00 1

passo 2  Viene eseguito il raggruppamento sul campo codHotel.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
gruppo 1 100
2 100 doppia 58,00 1
4 100 doppia 61,00 1

1 110 singola 60,00 1 gruppo 2 110

1 120 singola 100,00 1 gruppo 3 120


4 120 singola 200,00 1
55 140 doppia 99,00 1 gruppo 4 140
58 140 singola 100,00 1
4 150 doppia 250,00 1
5 150 singola 160,00 1
gruppo 5 150
6 150 doppia 350,00 1
7 150 singola 100,00 1

passo 3  Viene eseguita la funzione count presente in select, su ciascun gruppo.

13
Bocchi Cinzia 03/01/2015

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
gruppo 1 100 count=3
2 100 doppia 58,00 1
4 100 doppia 61,00 1

1 110 singola 60,00 1 gruppo 2 110 count=1

1 120 singola 100,00 1 gruppo 3 120 count=2


4 120 singola 200,00 1
55 140 doppia 99,00 1 gruppo 4 140 count=2
58 140 singola 100,00 1
4 150 doppia 250,00 1
5 150 singola 160,00 1
gruppo 5 150 count=3
6 150 doppia 350,00 1
7 150 singola 100,00 1

passo 4  Viene effettuata la proiezione sui campi della select.

codHotel NumStanzeOccupate
100 3
110 1
120 2
140 2
150 4

torna all’indice

14
Bocchi Cinzia 03/01/2015

Terza alternativa corretta

SELECT H.codHotel, H.nome, SUM (S.occupata) AS NumStanzeOccupate


FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel
GROUP BY H.codHotel, H.nome

I passi 1 e 2 sono identici al caso principale; vediamo cosa cambia in seguito.

passo 3  Viene effettuato il raggruppamento sui campi codHotel e nome della tabella
hotel (vedere i nomi colonne evidenziati in giallo).

codHotel nome ... ... occupata


100 Miramare ... ... 1
100 Miramare ... ... 1 gruppo 1: 100 Miramare
100 Miramare ... ... 0
100 Miramare ... ... 1
110 Marittimo ... ... 1
110 Marittimo ... ... 0 gruppo 2: 110 Marittimo
110 Marittimo ... ... 0
120 La baita ... ... 1
120 La baita ... ... 0 gruppo 3: 120 La baita
120 La baita ... ... 0
120 La baita ... ... 1
130 Miramare ... ... 0
130 Miramare ... ... 0 gruppo 4: 130 Miramare
130 Miramare ... ... 0
140 Fiesta ... ... 1
gruppo 5: 140 Fiesta
140 Fiesta ... ... 1
150 Fiesta ... ... 0
150 Fiesta ... ... 0
150 Fiesta ... ... 0
150 Fiesta ... ... 1 gruppo 6: 150 Fiesta
150 Fiesta ... ... 1
150 Fiesta ... ... 1
150 Fiesta ... ... 1

passo 4  Viene eseguita la funzione SUM presente in select, su ciascun gruppo.

15
Bocchi Cinzia 03/01/2015

codHotel nome ... ... occupata


100 Miramare ... ... 1
100 Miramare ... ... 1 gruppo 1: 100 Miramare sum=3
100 Miramare ... ... 0
100 Miramare ... ... 1
110 Marittimo ... ... 1
110 Marittimo ... ... 0 gruppo 2: 110 Marittimo sum=1
110 Marittimo ... ... 0
120 La baita ... ... 1
120 La baita ... ... 0 gruppo 3: 120 La baita sum=2
120 La baita ... ... 0
120 La baita ... ... 1
130 Miramare ... ... 0
130 Miramare ... ... 0 gruppo 4: 130 Miramare sum=0
130 Miramare ... ... 0
140 Fiesta ... ... 1
gruppo 5: 140 Fiesta sum=2
140 Fiesta ... ... 1
150 Fiesta ... ... 0
150 Fiesta ... ... 0
150 Fiesta ... ... 0
150 Fiesta ... ... 1 gruppo 6: 150 Fiesta sum=4
150 Fiesta ... ... 1
150 Fiesta ... ... 1
150 Fiesta ... ... 1

passo 5  Viene effettuata la proiezione sui campi della select.

codHotel nome NumStanzeOccupate


100 Miramare 3
110 Marittimo 1
120 La baita 2
130 Miramare 0
140 Fiesta 2
150 Fiesta 4

In questo caso il resultset ci fornisce un’informazione in più: l’hotel Miramare di codice 130
ha 0 stanze occupate.

torna all’indice

16
Bocchi Cinzia 03/01/2015

Quarta alternativa corretta

SELECT H.codHotel, SUM(S.occupata) AS NumStanzeOccupate


FROM stanza S
GROUP BY H.codHotel

Se non interessa il nome dell’Hotel, la terza alternativa può essere ricondotta a questo
caso.

passo 1  Viene effettuato il raggruppamento sul campo codHotel della tabella stanza

numStanza codHotel ... occupata


1 100 ... 1
2 100 ... 1 gruppo 1: 100
3 100 ... 0
4 100 ... 1
1 110 ... 1
gruppo 2: 110
2 110 ... 0
3 110 ... 0
1 120 ... 1
2 120 ... 0 gruppo 3: 120
3 120 ... 0
4 120 ... 1
21 130 ... 0
22 130 ... 0 gruppo 4: 130
25 130 ... 0
55 140 ... 1 gruppo 5: 140
58 140 ... 1
1 150 ... 0
2 150 ... 0
3 150 ... 0
4 150 ... 1 gruppo 6: 150
5 150 ... 1
6 150 ... 1
7 150 ... 1

passo 2  Viene eseguita la funzione SUM presente in select, su ciascun gruppo.

17
Bocchi Cinzia 03/01/2015

numStanza codHotel ... occupata


1 100 ... 1
2 100 ... 1 gruppo 1: 100 sum=3
3 100 ... 0
4 100 ... 1
1 110 ... 1
gruppo 2: 110 sum=1
2 110 ... 0
3 110 ... 0
1 120 ... 1
2 120 ... 0 gruppo 3: 120 sum=2
3 120 ... 0
4 120 ... 1
21 130 ... 0
22 130 ... 0 gruppo 4: 130 sum=0
25 130 ... 0
55 140 ... 1 gruppo 5: 140 sum=2
58 140 ... 1
1 150 ... 0
2 150 ... 0
3 150 ... 0
4 150 ... 1 gruppo 6: 150 sum=4
5 150 ... 1
6 150 ... 1
7 150 ... 1

passo 3  Viene effettuata la proiezione sui campi della select.

codHotel NumStanzeOccupate
100 3
110 1
120 2
130 0
140 2
150 4

In questo caso il resultset ci fornisce un’informazione in più: l’hotel di codice 130 ha 0


stanze occupate.

torna all’indice

18
Bocchi Cinzia 03/01/2015

Quinta alternativa corretta

SELECT H.nome, SUM(S.occupata) AS NumStanzeOccupate


FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel
GROUP BY H.codHotel, H.nome

Questa soluzione è simile alla terza alternativa, con la differenza che il campo codHotel
non compare nel resultset ma viene utilizzato per distinguere tra eventuali hotel omonimi.

nome NumStanzeOccupate
Miramare 3
Marittimo 1
La baita 2
Miramare 0
Fiesta 2
Fiesta 4

torna all’indice

Alternativa corretta solo in mancanza di hotel omonimi

SELECT H.nome, COUNT(*) AS NumStanzeOccupate


FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel AND S.occupata = 1
GROUP BY H.nome

I passi da 1 a 3 sono identici al caso principale mostrato, ma dal passo 4 si verificano dei
cambiamenti; vediamo quali.

passo 4  Viene effettuato il raggruppamento sul campo nome della tabella hotel
(vedere i nomi colonne evidenziati in giallo).

19
Bocchi Cinzia 03/01/2015

codHotel nome ... ...


100 Miramare ... ...
100 Miramare ... ... gruppo 1: Miramare
100 Miramare ... ...

110 Marittimo ... ... gruppo 2: Marittimo

120 La baita ... ... gruppo 3: La baita


120 La baita ... ...
140 Fiesta ... ...
140 Fiesta ... ...
150 Fiesta ... ...
gruppo 4: Fiesta
150 Fiesta ... ...
150 Fiesta ... ...
150 Fiesta ... ...

passo 5  Viene eseguita la funzione count presente in select, su ciascun gruppo.

codHotel nome ... ...


100 Miramare ... ...
100 Miramare ... ... gruppo 1: Miramare count=3
100 Miramare ... ...

110 Marittimo ... ... gruppo 2: Marittimo count=1

120 La baita ... ... gruppo 3: La baita count=2


120 La baita ... ...
140 Fiesta ... ...
140 Fiesta ... ...
150 Fiesta ... ...
150 Fiesta ... ... gruppo 4: Fiesta count=6
150 Fiesta ... ...
150 Fiesta ... ...

passo 6  Viene effettuata la proiezione sui campi della select.

nome NumStanzeOccupate
Miramare 3
Marittimo 1
La baita 2
Fiesta 6

torna all’indice

20
Bocchi Cinzia 03/01/2015

Alternativa corretta, analoga all’alternativa 2, ma non ottimizzata

SELECT H.codHotel, COUNT(*) AS NumStanzeOccupate


FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel AND S.occupata = 1
GROUP BY H.codHotel

codHotel NumStanzeOccupate
100 3
110 1
120 2
140 2
150 4

Il resultset fornisce le informazioni richieste, tuttavia viene effettuato del lavoro superfluo
per il prodotto cartesiano delle tabelle e l’equi-join. Se non serve il nome dell’hotel, è
sufficiente utilizzare la tabella stanza. Si veda la seconda alternativa corretta.

torna all’indice

Alternativa corretta, analoga all’alternativa 4, ma non ottimizzata

SELECT H.codHotel, SUM(S.occupata) AS NumStanzeOccupate


FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel
GROUP BY H.codHotel

Il resultset fornisce le informazioni richieste, tuttavia viene effettuato del lavoro superfluo
per il prodotto cartesiano delle tabelle e l’equi-join. Se non serve il nome dell’hotel, è
sufficiente utilizzare la tabella stanza. Si veda la quarta alternativa corretta.

codHotel NumStanzeOccupate
100 3
110 1
120 2
130 0
140 2
150 4

torna all’indice
21
Bocchi Cinzia 03/01/2015

Alternativa errata

SELECT H.nome
FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel AND S.occupata = 1
GROUP BY H.nome

I passi da 1 a 3 sono identici al caso principale mostrato, ma dal passo 4 si verificano dei
cambiamenti; vediamo quali.

passo 4  Viene effettuato il raggruppamento sul campo nome della tabella hotel
(vedere i nomi colonne evidenziati in giallo).

codHotel nome ... ...


100 Miramare ... ...
100 Miramare ... ... gruppo 1: Miramare
100 Miramare ... ...

110 Marittimo ... ... gruppo 2: Marittimo

120 La baita ... ... gruppo 3: La baita


120 La baita ... ...
140 Fiesta ... ...
140 Fiesta ... ...
150 Fiesta ... ...
gruppo 4: Fiesta
150 Fiesta ... ...
150 Fiesta ... ...
150 Fiesta ... ...

passo 5  vengono proiettati i campi presenti in select per ogni gruppo

nome
Miramare
Marittimo
La baita
Fiesta

Come si può osservare, il resultset non ci fornisce le informazioni richieste.

torna all’indice

22
Bocchi Cinzia 03/01/2015

3) Per ogni hotel trovare il prezzo minimo e massimo delle stanze,


indipendentemente dalla tipologia

SELECT H.codHotel, H.nome, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel
GROUP BY H.codHotel, H.nome

passo 1  Viene eseguito il prodotto cartesiano delle tabelle presenti in from: ogni riga
della tabella hotel viene combinata con tutte le righe della tabella stanza.

codHotel nome citta numStanza codHotel tipo prezzo occupata


100 Miramare Rimini 1 100 singola 60,00 1
100 Miramare Rimini 2 100 doppia 58,00 1
100 Miramare Rimini 3 100 singola 65,00 0
100 Miramare Rimini 4 100 doppia 61,00 1
100 Miramare Rimini 1 110 singola 60,00 1
100 Miramare Rimini 2 110 doppia 80,00 0
100 Miramare Rimini 3 110 singola 95,00 0
100 Miramare Rimini 1 120 singola 100,00 1
100 Miramare Rimini 2 120 doppia 95,00 0
100 Miramare Rimini 3 120 singola 150,00 0
100 Miramare Rimini 4 120 singola 200,00 1
100 Miramare Rimini 21 130 doppia 250,00 0
100 Miramare Rimini 22 130 singola 300,00 0
100 Miramare Rimini 25 130 singola 150,00 0
100 Miramare Rimini 55 140 doppia 99,00 1
100 Miramare Rimini 58 140 singola 100,00 1
100 Miramare Rimini 1 150 doppia 250,00 0
100 Miramare Rimini 2 150 singola 180,00 0
100 Miramare Rimini 3 150 singola 150,00 0
100 Miramare Rimini 4 150 doppia 250,00 1
100 Miramare Rimini 5 150 singola 160,00 1
100 Miramare Rimini 6 150 doppia 350,00 1
100 Miramare Rimini 7 150 singola 100,00 1
110 Marittimo Rimini 1 100 singola 60,00 1
110 Marittimo Rimini 2 100 doppia 58,00 1
110 Marittimo Rimini 3 100 singola 65,00 0
110 Marittimo Rimini 4 100 doppia 61,00 1
110 Marittimo Rimini 1 110 singola 60,00 1
110 Marittimo Rimini 2 110 doppia 80,00 0
110 Marittimo Rimini 3 110 singola 95,00 0
110 Marittimo Rimini 1 120 singola 100,00 1
110 Marittimo Rimini 2 120 doppia 95,00 0
23
Bocchi Cinzia 03/01/2015

110 Marittimo Rimini 3 120 singola 150,00 0


110 Marittimo Rimini 4 120 singola 200,00 1
110 Marittimo Rimini 21 130 doppia 250,00 0
110 Marittimo Rimini 22 130 singola 300,00 0
110 Marittimo Rimini 25 130 singola 150,00 0
110 Marittimo Rimini 55 140 doppia 99,00 1
110 Marittimo Rimini 58 140 singola 100,00 1
110 Marittimo Rimini 1 150 doppia 250,00 0
110 Marittimo Rimini 2 150 singola 180,00 0
110 Marittimo Rimini 3 150 singola 150,00 0
110 Marittimo Rimini 4 150 doppia 250,00 1
110 Marittimo Rimini 5 150 singola 160,00 1
110 Marittimo Rimini 6 150 doppia 350,00 1
110 Marittimo Rimini 7 150 singola 100,00 1
120 La baita Aosta 1 100 singola 60,00 1
120 La baita Aosta 2 100 doppia 58,00 1
120 La baita Aosta 3 100 singola 65,00 0
120 La baita Aosta 4 100 doppia 61,00 1
120 La baita Aosta 1 110 singola 60,00 1
120 La baita Aosta 2 110 doppia 80,00 0
120 La baita Aosta 3 110 singola 95,00 0
120 La baita Aosta 1 120 singola 100,00 1
120 La baita Aosta 2 120 doppia 95,00 0
120 La baita Aosta 3 120 singola 150,00 0
120 La baita Aosta 4 120 singola 200,00 1
120 La baita Aosta 21 130 doppia 250,00 0
120 La baita Aosta 22 130 singola 300,00 0
120 La baita Aosta 25 130 singola 150,00 0
120 La baita Aosta 55 140 doppia 99,00 1
120 La baita Aosta 58 140 singola 100,00 1
120 La baita Aosta 1 150 doppia 250,00 0
120 La baita Aosta 2 150 singola 180,00 0
120 La baita Aosta 3 150 singola 150,00 0
120 La baita Aosta 4 150 doppia 250,00 1
120 La baita Aosta 5 150 singola 160,00 1
120 La baita Aosta 6 150 doppia 350,00 1
120 La baita Aosta 7 150 singola 100,00 1
130 Miramare Napoli 1 100 singola 60,00 1
130 Miramare Napoli 2 100 doppia 58,00 1
130 Miramare Napoli 3 100 singola 65,00 0
130 Miramare Napoli 4 100 doppia 61,00 1
130 Miramare Napoli 1 110 singola 60,00 1
130 Miramare Napoli 2 110 doppia 80,00 0
130 Miramare Napoli 3 110 singola 95,00 0
130 Miramare Napoli 1 120 singola 100,00 1
130 Miramare Napoli 2 120 doppia 95,00 0
130 Miramare Napoli 3 120 singola 150,00 0
130 Miramare Napoli 4 120 singola 200,00 1
130 Miramare Napoli 21 130 doppia 250,00 0
24
Bocchi Cinzia 03/01/2015

130 Miramare Napoli 22 130 singola 300,00 0


130 Miramare Napoli 25 130 singola 150,00 0
130 Miramare Napoli 55 140 doppia 99,00 1
130 Miramare Napoli 58 140 singola 100,00 1
130 Miramare Napoli 1 150 doppia 250,00 0
130 Miramare Napoli 2 150 singola 180,00 0
130 Miramare Napoli 3 150 singola 150,00 0
130 Miramare Napoli 4 150 doppia 250,00 1
130 Miramare Napoli 5 150 singola 160,00 1
130 Miramare Napoli 6 150 doppia 350,00 1
130 Miramare Napoli 7 150 singola 100,00 1
140 Fiesta Rimini 1 100 singola 60,00 1
140 Fiesta Rimini 2 100 doppia 58,00 1
140 Fiesta Rimini 3 100 singola 65,00 0
140 Fiesta Rimini 4 100 doppia 61,00 1
140 Fiesta Rimini 1 110 singola 60,00 1
140 Fiesta Rimini 2 110 doppia 80,00 0
140 Fiesta Rimini 3 110 singola 95,00 0
140 Fiesta Rimini 1 120 singola 100,00 1
140 Fiesta Rimini 2 120 doppia 95,00 0
140 Fiesta Rimini 3 120 singola 150,00 0
140 Fiesta Rimini 4 120 singola 200,00 1
140 Fiesta Rimini 21 130 doppia 250,00 0
140 Fiesta Rimini 22 130 singola 300,00 0
140 Fiesta Rimini 25 130 singola 150,00 0
140 Fiesta Rimini 55 140 doppia 99,00 1
140 Fiesta Rimini 58 140 singola 100,00 1
140 Fiesta Rimini 1 150 doppia 250,00 0
140 Fiesta Rimini 2 150 singola 180,00 0
140 Fiesta Rimini 3 150 singola 150,00 0
140 Fiesta Rimini 4 150 doppia 250,00 1
140 Fiesta Rimini 5 150 singola 160,00 1
140 Fiesta Rimini 6 150 doppia 350,00 1
140 Fiesta Rimini 7 150 singola 100,00 1
150 Fiesta Torino 1 100 singola 60,00 1
150 Fiesta Torino 2 100 doppia 58,00 1
150 Fiesta Torino 3 100 singola 65,00 0
150 Fiesta Torino 4 100 doppia 61,00 1
150 Fiesta Torino 1 110 singola 60,00 1
150 Fiesta Torino 2 110 doppia 80,00 0
150 Fiesta Torino 3 110 singola 95,00 0
150 Fiesta Torino 1 120 singola 100,00 1
150 Fiesta Torino 2 120 doppia 95,00 0
150 Fiesta Torino 3 120 singola 150,00 0
150 Fiesta Torino 4 120 singola 200,00 1
150 Fiesta Torino 21 130 doppia 250,00 0
150 Fiesta Torino 22 130 singola 300,00 0
150 Fiesta Torino 25 130 singola 150,00 0
150 Fiesta Torino 55 140 doppia 99,00 1
25
Bocchi Cinzia 03/01/2015

150 Fiesta Torino 58 140 singola 100,00 1


150 Fiesta Torino 1 150 doppia 250,00 0
150 Fiesta Torino 2 150 singola 180,00 0
150 Fiesta Torino 3 150 singola 150,00 0
150 Fiesta Torino 4 150 doppia 250,00 1
150 Fiesta Torino 5 150 singola 160,00 1
150 Fiesta Torino 6 150 doppia 350,00 1
150 Fiesta Torino 7 150 singola 100,00 1

passo 2  Viene applicata la condizione di equi join H.codHotel = S.codHotel che


consente di mantenere solo le righe formate da record tra loro correlati (vedere le colonne
con sfondo grigio nella precedente tabella); le righe che non soddisfano tale condizione
vengono eliminate.

codHotel nome citta numStanza codHotel tipo prezzo occupata


100 Miramare Rimini 1 100 singola 60,00 1
100 Miramare Rimini 2 100 doppia 58,00 1
100 Miramare Rimini 3 100 singola 65,00 0
100 Miramare Rimini 4 100 doppia 61,00 1
110 Marittimo Rimini 1 110 singola 60,00 1
110 Marittimo Rimini 2 110 doppia 80,00 0
110 Marittimo Rimini 3 110 singola 95,00 0
120 La baita Aosta 1 120 singola 100,00 1
120 La baita Aosta 2 120 doppia 95,00 0
120 La baita Aosta 3 120 singola 150,00 0
120 La baita Aosta 4 120 singola 200,00 1
130 Miramare Napoli 21 130 doppia 250,00 0
130 Miramare Napoli 22 130 singola 300,00 0
130 Miramare Napoli 25 130 singola 150,00 0
140 Fiesta Rimini 55 140 doppia 99,00 1
140 Fiesta Rimini 58 140 singola 100,00 1
150 Fiesta Torino 1 150 doppia 250,00 0
150 Fiesta Torino 2 150 singola 180,00 0
150 Fiesta Torino 3 150 singola 150,00 0
150 Fiesta Torino 4 150 doppia 250,00 1
150 Fiesta Torino 5 150 singola 160,00 1
150 Fiesta Torino 6 150 doppia 350,00 1
150 Fiesta Torino 7 150 singola 100,00 1

passo 3  Viene effettuato il raggruppamento sui campi codHotel e nome della tabella
hotel (vedere i nomi colonne evidenziati in giallo).

26
Bocchi Cinzia 03/01/2015

codHotel nome ... ... prezzo ...


100 Miramare ... ... 60,00 ...
100 Miramare ... ... 58,00 ... gruppo 1: 100 Miramare
100 Miramare ... ... 65,00 ...
100 Miramare ... ... 61,00 ...
110 Marittimo ... ... 60,00 ...
110 Marittimo ... ... 80,00 ... gruppo 2: 110 Marittimo
110 Marittimo ... ... 95,00 ...
120 La baita ... ... 100,00 ...
120 La baita ... ... 95,00 ... gruppo 3: 120 La baita
120 La baita ... ... 150,00 ...
120 La baita ... ... 200,00 ...
130 Miramare ... ... 250,00 ...
130 Miramare ... ... 300,00 ... gruppo 4: 130 Miramare
130 Miramare ... ... 150,00 ...
140 Fiesta ... ... 99,00 ... gruppo 5: 140 Fiesta
140 Fiesta ... ... 100,00 ...
150 Fiesta ... ... 250,00 ...
150 Fiesta ... ... 180,00 ...
150 Fiesta ... ... 150,00 ... gruppo 6: 150 Fiesta
150 Fiesta ... ... 250,00 ...
150 Fiesta ... ... 160,00 ...
150 Fiesta ... ... 350,00 ...
150 Fiesta ... ... 100,00 ...

passo 4 Vengono eseguite le funzioni MIN e MAX presenti nella select, per ciascun
gruppo.

codHotel nome ... ... prezzo ...


100 Miramare ... ... 60,00 ...
100 Miramare ... ... 58,00 ... gruppo 1: 100 Miramare min=58 max=65
100 Miramare ... ... 65,00 ...
100 Miramare ... ... 61,00 ...
110 Marittimo ... ... 60,00 ... gruppo 2: 110 Marittimo min=60 max=95
110 Marittimo ... ... 80,00 ...
110 Marittimo ... ... 95,00 ...
120 La baita ... ... 100,00 ...
120 La baita ... ... 95,00 ... gruppo 3: 120 La baita min=95 max=200
120 La baita ... ... 150,00 ...
120 La baita ... ... 200,00 ...
130 Miramare ... ... 250,00 ... gruppo 4: 130 Miramare min=150 max=300
130 Miramare ... ... 300,00 ...
130 Miramare ... ... 150,00 ...
140 Fiesta ... ... 99,00 ... gruppo 5: 140 Fiesta min=99 max=100
140 Fiesta ... ... 100,00 ...
150 Fiesta ... ... 250,00 ...
150 Fiesta ... ... 180,00 ...
27
Bocchi Cinzia 03/01/2015

150 Fiesta ... ... 150,00 ...


150 Fiesta ... ... 250,00 ...
150 Fiesta ... ... 160,00 ... gruppo 6: 150 Fiesta min=100 max=350
150 Fiesta ... ... 350,00 ...
150 Fiesta ... ... 100,00 ...

passo 5  Viene effettuata la proiezione sui campi della select.

codHotel nome PrezzoMinimo PrezzoMassimo


100 Miramare 58 65
110 Marittimo 60 95
120 La baita 95 200
130 Miramare 150 300
140 Fiesta 99 100
150 Fiesta 100 350

torna all’indice

Prima alternativa corretta

SELECT H.nome, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel
GROUP BY H.codHotel, H.nome

I passi da 1 a 4 sono identici a quelli della soluzione principale.

passo 5  Viene effettuata la proiezione sui campi della select.

nome PrezzoMinimo PrezzoMassimo


Miramare 58 65
Marittimo 60 95
La baita 95 200
Miramare 150 300
Fiesta 99 100
Fiesta 100 350

Come si può notare, non è presente la colonna codHotel, ma gli hotel che hanno lo stesso
nome vengono mantenuti distinti.

torna all’indice
28
Bocchi Cinzia 03/01/2015

Seconda alternativa corretta

SELECT S.codHotel, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM stanza S
GROUP BY S.codHotel

L’alternativa è utile nel caso non interessi il nome dell’hotel.

passo 1  Viene effettuato il raggruppamento sul campo codHotel della tabella stanza

numStanza codHotel ... prezzo ...


1 100 ... 60,00 ...
2 100 ... 58,00 ... gruppo 1: 100
3 100 ... 65,00 ...
4 100 ... 61,00 ...
1 110 ... 60,00 ...
2 110 ... 80,00 ... gruppo 2: 110
3 110 ... 95,00 ...
1 120 ... 100,00 ...
2 120 ... 95,00 ... gruppo 3: 120
3 120 ... 150,00 ...
4 120 ... 200,00 ...
21 130 ... 250,00 ...
22 130 ... 300,00 ... gruppo 4: 130
25 130 ... 150,00 ...
55 140 ... 99,00 ... gruppo 5: 140
58 140 ... 100,00 ...
1 150 ... 250,00 ...
2 150 ... 180,00 ...
3 150 ... 150,00 ...
4 150 ... 250,00 ... gruppo 6: 150
5 150 ... 160,00 ...
6 150 ... 350,00 ...
7 150 ... 100,00 ...

passo 2 Vengono eseguite le funzioni MIN e MAX presenti nella select, per ciascun
gruppo.

29
Bocchi Cinzia 03/01/2015

numStanza codHotel ... prezzo ...


1 100 ... 60,00 ...
2 100 ... 58,00 ... gruppo 1: 100 min=58 max=65
3 100 ... 65,00 ...
4 100 ... 61,00 ...
1 110 ... 60,00 ...
2 110 ... 80,00 ... gruppo 2: 110 min=60 max=95
3 110 ... 95,00 ...
1 120 ... 100,00 ...
2 120 ... 95,00 ... gruppo 3: 120 min=95 max=200
3 120 ... 150,00 ...
4 120 ... 200,00 ...
21 130 ... 250,00 ...
22 130 ... 300,00 ... gruppo 4: 130 min=150 max=300
25 130 ... 150,00 ...
55 140 ... 99,00 ... gruppo 5: 140 min=99 max=100
58 140 ... 100,00 ...
1 150 ... 250,00 ...
2 150 ... 180,00 ...
3 150 ... 150,00 ...
gruppo 6: 150 150 min=100 max=350
4 150 ... 250,00 ...
5 150 ... 160,00 ...
6 150 ... 350,00 ...
7 150 ... 100,00 ...

passo 3  Viene effettuata la proiezione sui campi della select.

codHotel PrezzoMinimo PrezzoMassimo


100 58 65
110 60 95
120 95 200
130 150 300
140 99 100
150 100 350

torna all’indice

30
Bocchi Cinzia 03/01/2015

Alternativa corretta solo in mancanza di hotel omonimi

SELECT H.nome, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel
GROUP BY H.nome

I passi 1 e 2 sono identici alla soluzione principale.

passo 3  Viene effettuato il raggruppamento sul campo nome della tabella hotel
(vedere i nomi colonne evidenziati in giallo).

codHotel nome ... ... prezzo ...


100 Miramare ... ... 60,00 ...
100 Miramare ... ... 58,00 ...
100 Miramare ... ... 65,00 ...
100 Miramare ... ... 61,00 ... gruppo 1: Miramare
130 Miramare ... ... 250,00 ...
130 Miramare ... ... 300,00 ...
130 Miramare ... ... 150,00 ...
110 Marittimo ... ... 60,00 ...
110 Marittimo ... ... 80,00 ... gruppo 2: Marittimo
110 Marittimo ... ... 95,00 ...
120 La baita ... ... 100,00 ...
120 La baita ... ... 95,00 ... gruppo 3: La baita
120 La baita ... ... 150,00 ...
120 La baita ... ... 200,00 ...
140 Fiesta ... ... 99,00 ...
140 Fiesta ... ... 100,00 ...
150 Fiesta ... ... 250,00 ...
150 Fiesta ... ... 180,00 ... gruppo 4: Fiesta
150 Fiesta ... ... 150,00 ...
150 Fiesta ... ... 250,00 ...
150 Fiesta ... ... 160,00 ...
150 Fiesta ... ... 350,00 ...
150 Fiesta ... ... 100,00 ...

passo 4 Vengono eseguite le funzioni MIN e MAX presenti nella select, per ciascun
gruppo.

31
Bocchi Cinzia 03/01/2015

codHotel nome ... ... prezzo ...


100 Miramare ... ... 60,00 ...
100 Miramare ... ... 58,00 ...
100 Miramare ... ... 65,00 ...
100 Miramare ... ... 61,00 ... gruppo 1: Miramare min=58 max= 300
130 Miramare ... ... 250,00 ...
130 Miramare ... ... 300,00 ...
130 Miramare ... ... 150,00 ...
110 Marittimo ... ... 60,00 ...
110 Marittimo ... ... 80,00 ... gruppo 2: Marittimo min=60 max=95
110 Marittimo ... ... 95,00 ...
120 La baita ... ... 100,00 ...
120 La baita ... ... 95,00 ... gruppo 3: La baita min=95 max=200
120 La baita ... ... 150,00 ...
120 La baita ... ... 200,00 ...
140 Fiesta ... ... 99,00 ...
140 Fiesta ... ... 100,00 ...
150 Fiesta ... ... 250,00 ...
150 Fiesta ... ... 180,00 ... gruppo 4: Fiesta min=99 max=350
150 Fiesta ... ... 150,00 ...
150 Fiesta ... ... 250,00 ...
150 Fiesta ... ... 160,00 ...
150 Fiesta ... ... 350,00 ...
150 Fiesta ... ... 100,00 ...

passo 5  Viene effettuata la proiezione sui campi della select.

nome PrezzoMinimo PrezzoMassimo


Miramare 58 300
Marittimo 60 95
La baita 95 200
Fiesta 99 350

torna all’indice

32
Bocchi Cinzia 03/01/2015

Alternativa corretta, analoga all’alternativa 2, ma non ottimizzata

SELECT H.codHotel, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel
GROUP BY H.codHotel

Il resultset fornisce le informazioni richieste, tuttavia viene effettuato del lavoro superfluo
per il prodotto cartesiano delle tabelle e l’equi-join. Se non serve il nome dell’hotel, è
sufficiente utilizzare la tabella stanza. Si veda la seconda alternativa corretta.

codHotel PrezzoMinimo PrezzoMassimo


100 58 65
110 60 95
120 95 200
130 150 300
140 99 100
150 100 350

torna all’indice

Alternativa incompleta

SELECT H.codHotel, H.nome, MAX(S.prezzo) AS PrezzoMassimo


FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel
GROUP BY H.codHotel, H.nome

I passi sono da 1 a 3 sono identici alla soluzione principale. Al passo 4 non viene
effettuato il calcolo del minimo e, di conseguenza, il resultset è incompleto poiché non
contiene il prezzo minimo.

codHotel nome PrezzoMassimo


100 Miramare 65
110 Marittimo 95
120 La baita 200
130 Miramare 300
140 Fiesta 100
150 Fiesta 350

torna all’indice

33
Bocchi Cinzia 03/01/2015

Alternativa errata

SELECT S.codHotel, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM stanza S
WHERE S.tipo = “qualsiasi”
GROUP BY S.codHotel

passo 1  La condizione in where viene applicata alla tabella stanza. La tipologia di


stanza qualsiasi non esiste nella realtà. Nonostante la tabella mostri solo esempi di stanze
singole e doppie, possiamo avere altre tipologie come triple, suite, ecc., ma non la
tipologia qualsiasi. Tale condizione, quindi, elimina tutte le righe della tabella stanza.
Qualsiasi altra operazione effettuata in seguito restituisce un resultset vuoto.

torna all’indice

34
Bocchi Cinzia 03/01/2015

4) Per ogni hotel trovare il prezzo minimo e massimo delle stanze singole

SELECT H.codHotel, H.nome, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel AND S.tipo = ‘singola’
GROUP BY H.codHotel, H.nome

passo 1  Viene eseguito il prodotto cartesiano delle tabelle presenti in from: ogni riga
della tabella hotel viene combinata con tutte le righe della tabella stanza.

codHotel nome citta numStanza codHotel tipo prezzo occupata


100 Miramare Rimini 1 100 singola 60,00 1
100 Miramare Rimini 2 100 doppia 58,00 1
100 Miramare Rimini 3 100 singola 65,00 0
100 Miramare Rimini 4 100 doppia 61,00 1
100 Miramare Rimini 1 110 singola 60,00 1
100 Miramare Rimini 2 110 doppia 80,00 0
100 Miramare Rimini 3 110 singola 95,00 0
100 Miramare Rimini 1 120 singola 100,00 1
100 Miramare Rimini 2 120 doppia 95,00 0
100 Miramare Rimini 3 120 singola 150,00 0
100 Miramare Rimini 4 120 singola 200,00 1
100 Miramare Rimini 21 130 doppia 250,00 0
100 Miramare Rimini 22 130 singola 300,00 0
100 Miramare Rimini 25 130 singola 150,00 0
100 Miramare Rimini 55 140 doppia 99,00 1
100 Miramare Rimini 58 140 singola 100,00 1
100 Miramare Rimini 1 150 doppia 250,00 0
100 Miramare Rimini 2 150 singola 180,00 0
100 Miramare Rimini 3 150 singola 150,00 0
100 Miramare Rimini 4 150 doppia 250,00 1
100 Miramare Rimini 5 150 singola 160,00 1
100 Miramare Rimini 6 150 doppia 350,00 1
100 Miramare Rimini 7 150 singola 100,00 1
110 Marittimo Rimini 1 100 singola 60,00 1
110 Marittimo Rimini 2 100 doppia 58,00 1
110 Marittimo Rimini 3 100 singola 65,00 0
110 Marittimo Rimini 4 100 doppia 61,00 1
110 Marittimo Rimini 1 110 singola 60,00 1
110 Marittimo Rimini 2 110 doppia 80,00 0
110 Marittimo Rimini 3 110 singola 95,00 0
110 Marittimo Rimini 1 120 singola 100,00 1
110 Marittimo Rimini 2 120 doppia 95,00 0
110 Marittimo Rimini 3 120 singola 150,00 0
110 Marittimo Rimini 4 120 singola 200,00 1
35
Bocchi Cinzia 03/01/2015

110 Marittimo Rimini 21 130 doppia 250,00 0


110 Marittimo Rimini 22 130 singola 300,00 0
110 Marittimo Rimini 25 130 singola 150,00 0
110 Marittimo Rimini 55 140 doppia 99,00 1
110 Marittimo Rimini 58 140 singola 100,00 1
110 Marittimo Rimini 1 150 doppia 250,00 0
110 Marittimo Rimini 2 150 singola 180,00 0
110 Marittimo Rimini 3 150 singola 150,00 0
110 Marittimo Rimini 4 150 doppia 250,00 1
110 Marittimo Rimini 5 150 singola 160,00 1
110 Marittimo Rimini 6 150 doppia 350,00 1
110 Marittimo Rimini 7 150 singola 100,00 1
120 La baita Aosta 1 100 singola 60,00 1
120 La baita Aosta 2 100 doppia 58,00 1
120 La baita Aosta 3 100 singola 65,00 0
120 La baita Aosta 4 100 doppia 61,00 1
120 La baita Aosta 1 110 singola 60,00 1
120 La baita Aosta 2 110 doppia 80,00 0
120 La baita Aosta 3 110 singola 95,00 0
120 La baita Aosta 1 120 singola 100,00 1
120 La baita Aosta 2 120 doppia 95,00 0
120 La baita Aosta 3 120 singola 150,00 0
120 La baita Aosta 4 120 singola 200,00 1
120 La baita Aosta 21 130 doppia 250,00 0
120 La baita Aosta 22 130 singola 300,00 0
120 La baita Aosta 25 130 singola 150,00 0
120 La baita Aosta 55 140 doppia 99,00 1
120 La baita Aosta 58 140 singola 100,00 1
120 La baita Aosta 1 150 doppia 250,00 0
120 La baita Aosta 2 150 singola 180,00 0
120 La baita Aosta 3 150 singola 150,00 0
120 La baita Aosta 4 150 doppia 250,00 1
120 La baita Aosta 5 150 singola 160,00 1
120 La baita Aosta 6 150 doppia 350,00 1
120 La baita Aosta 7 150 singola 100,00 1
130 Miramare Napoli 1 100 singola 60,00 1
130 Miramare Napoli 2 100 doppia 58,00 1
130 Miramare Napoli 3 100 singola 65,00 0
130 Miramare Napoli 4 100 doppia 61,00 1
130 Miramare Napoli 1 110 singola 60,00 1
130 Miramare Napoli 2 110 doppia 80,00 0
130 Miramare Napoli 3 110 singola 95,00 0
130 Miramare Napoli 1 120 singola 100,00 1
130 Miramare Napoli 2 120 doppia 95,00 0
130 Miramare Napoli 3 120 singola 150,00 0
130 Miramare Napoli 4 120 singola 200,00 1
130 Miramare Napoli 21 130 doppia 250,00 0
130 Miramare Napoli 22 130 singola 300,00 0
130 Miramare Napoli 25 130 singola 150,00 0
36
Bocchi Cinzia 03/01/2015

130 Miramare Napoli 55 140 doppia 99,00 1


130 Miramare Napoli 58 140 singola 100,00 1
130 Miramare Napoli 1 150 doppia 250,00 0
130 Miramare Napoli 2 150 singola 180,00 0
130 Miramare Napoli 3 150 singola 150,00 0
130 Miramare Napoli 4 150 doppia 250,00 1
130 Miramare Napoli 5 150 singola 160,00 1
130 Miramare Napoli 6 150 doppia 350,00 1
130 Miramare Napoli 7 150 singola 100,00 1
140 Fiesta Rimini 1 100 singola 60,00 1
140 Fiesta Rimini 2 100 doppia 58,00 1
140 Fiesta Rimini 3 100 singola 65,00 0
140 Fiesta Rimini 4 100 doppia 61,00 1
140 Fiesta Rimini 1 110 singola 60,00 1
140 Fiesta Rimini 2 110 doppia 80,00 0
140 Fiesta Rimini 3 110 singola 95,00 0
140 Fiesta Rimini 1 120 singola 100,00 1
140 Fiesta Rimini 2 120 doppia 95,00 0
140 Fiesta Rimini 3 120 singola 150,00 0
140 Fiesta Rimini 4 120 singola 200,00 1
140 Fiesta Rimini 21 130 doppia 250,00 0
140 Fiesta Rimini 22 130 singola 300,00 0
140 Fiesta Rimini 25 130 singola 150,00 0
140 Fiesta Rimini 55 140 doppia 99,00 1
140 Fiesta Rimini 58 140 singola 100,00 1
140 Fiesta Rimini 1 150 doppia 250,00 0
140 Fiesta Rimini 2 150 singola 180,00 0
140 Fiesta Rimini 3 150 singola 150,00 0
140 Fiesta Rimini 4 150 doppia 250,00 1
140 Fiesta Rimini 5 150 singola 160,00 1
140 Fiesta Rimini 6 150 doppia 350,00 1
140 Fiesta Rimini 7 150 singola 100,00 1
150 Fiesta Torino 1 100 singola 60,00 1
150 Fiesta Torino 2 100 doppia 58,00 1
150 Fiesta Torino 3 100 singola 65,00 0
150 Fiesta Torino 4 100 doppia 61,00 1
150 Fiesta Torino 1 110 singola 60,00 1
150 Fiesta Torino 2 110 doppia 80,00 0
150 Fiesta Torino 3 110 singola 95,00 0
150 Fiesta Torino 1 120 singola 100,00 1
150 Fiesta Torino 2 120 doppia 95,00 0
150 Fiesta Torino 3 120 singola 150,00 0
150 Fiesta Torino 4 120 singola 200,00 1
150 Fiesta Torino 21 130 doppia 250,00 0
150 Fiesta Torino 22 130 singola 300,00 0
150 Fiesta Torino 25 130 singola 150,00 0
150 Fiesta Torino 55 140 doppia 99,00 1
150 Fiesta Torino 58 140 singola 100,00 1
150 Fiesta Torino 1 150 doppia 250,00 0
37
Bocchi Cinzia 03/01/2015

150 Fiesta Torino 2 150 singola 180,00 0


150 Fiesta Torino 3 150 singola 150,00 0
150 Fiesta Torino 4 150 doppia 250,00 1
150 Fiesta Torino 5 150 singola 160,00 1
150 Fiesta Torino 6 150 doppia 350,00 1
150 Fiesta Torino 7 150 singola 100,00 1

passo 2  Viene applicata la condizione di equi join H.codHotel = S.codHotel che


consente di mantenere solo le righe formate da record tra loro correlati (vedere le colonne
con sfondo grigio nella precedente tabella); le righe che non soddisfano tale condizione
vengono eliminate.

codHotel nome citta numStanza codHotel tipo prezzo occupata


100 Miramare Rimini 1 100 singola 60,00 1
100 Miramare Rimini 2 100 doppia 58,00 1
100 Miramare Rimini 3 100 singola 65,00 0
100 Miramare Rimini 4 100 doppia 61,00 1
110 Marittimo Rimini 1 110 singola 60,00 1
110 Marittimo Rimini 2 110 doppia 80,00 0
110 Marittimo Rimini 3 110 singola 95,00 0
120 La baita Aosta 1 120 singola 100,00 1
120 La baita Aosta 2 120 doppia 95,00 0
120 La baita Aosta 3 120 singola 150,00 0
120 La baita Aosta 4 120 singola 200,00 1
130 Miramare Napoli 21 130 doppia 250,00 0
130 Miramare Napoli 22 130 singola 300,00 0
130 Miramare Napoli 25 130 singola 150,00 0
140 Fiesta Rimini 55 140 doppia 99,00 1
140 Fiesta Rimini 58 140 singola 100,00 1
150 Fiesta Torino 1 150 doppia 250,00 0
150 Fiesta Torino 2 150 singola 180,00 0
150 Fiesta Torino 3 150 singola 150,00 0
150 Fiesta Torino 4 150 doppia 250,00 1
150 Fiesta Torino 5 150 singola 160,00 1
150 Fiesta Torino 6 150 doppia 350,00 1
150 Fiesta Torino 7 150 singola 100,00 1

passo 3  Viene applicata la condizione where S.tipo = ‘singola’: le righe relative a


stanze con tipologia diversa vengono eliminate (vedere la colonna con sfondo grigio nella
precedente tabella).

38
Bocchi Cinzia 03/01/2015

codHotel nome citta numStanza codHotel tipo prezzo occupata


100 Miramare Rimini 1 100 singola 60,00 1
100 Miramare Rimini 3 100 singola 65,00 0
110 Marittimo Rimini 1 110 singola 60,00 1
110 Marittimo Rimini 3 110 singola 95,00 0
120 La baita Aosta 1 120 singola 100,00 1
120 La baita Aosta 3 120 singola 150,00 0
120 La baita Aosta 4 120 singola 200,00 1
130 Miramare Napoli 22 130 singola 300,00 0
130 Miramare Napoli 25 130 singola 150,00 0
140 Fiesta Rimini 58 140 singola 100,00 1
150 Fiesta Torino 2 150 singola 180,00 0
150 Fiesta Torino 3 150 singola 150,00 0
150 Fiesta Torino 5 150 singola 160,00 1
150 Fiesta Torino 7 150 singola 100,00 1

passo 4  Viene effettuato il raggruppamento sui campi codHotel e nome della tabella
hotel (vedere i nomi colonne evidenziati in giallo).

codHotel nome ... ... prezzo ...


100 Miramare ... ... 60,00 ... gruppo 1: 100 Miramare
100 Miramare ... ... 65,00 ...
110 Marittimo ... ... 60,00 ...
gruppo 2: 110 Marittimo
110 Marittimo ... ... 95,00 ...
120 La baita ... ... 100,00 ...
120 La baita ... ... 150,00 ... gruppo 3: 120 La baita
120 La baita ... ... 200,00 ...
130 Miramare ... ... 300,00 ...
gruppo 4: 130 Miramare
130 Miramare ... ... 150,00 ...

140 Fiesta ... ... 100,00 ... gruppo 5: 140 Fiesta

150 Fiesta ... ... 180,00 ...


150 Fiesta ... ... 150,00 ... gruppo 6: 150 Fiesta
150 Fiesta ... ... 160,00 ...
150 Fiesta ... ... 100,00 ...

passo 5 Vengono eseguite le funzioni MIN e MAX presenti nella select, per ciascun
gruppo.

39
Bocchi Cinzia 03/01/2015

codHotel nome ... ... prezzo ...


100 Miramare ... ... 60,00 ... gruppo 1: 100 Miramare min=60 max=65
100 Miramare ... ... 65,00 ...
110 Marittimo ... ... 60,00 ...
gruppo 2: 110 Marittimo min=60 max=95
110 Marittimo ... ... 95,00 ...
120 La baita ... ... 100,00 ...
120 La baita ... ... 150,00 ... gruppo 3: 120 La baita min=100 max=200
120 La baita ... ... 200,00 ...
130 Miramare ... ... 300,00 ...
gruppo 4: 130 Miramare min=150 max=300
130 Miramare ... ... 150,00 ...

140 Fiesta ... ... 100,00 ... gruppo 5: 140 Fiesta min=100 max=100

150 Fiesta ... ... 180,00 ...


150 Fiesta ... ... 150,00 ... gruppo 6: 150 Fiesta min=100 max=180
150 Fiesta ... ... 160,00 ...
150 Fiesta ... ... 100,00 ...

passo 6  Viene effettuata la proiezione sui campi della select.

codHotel nome PrezzoMinimo PrezzoMassimo


100 Miramare 60 65
110 Marittimo 60 95
120 La baita 100 200
130 Miramare 150 300
140 Fiesta 100 100
150 Fiesta 100 180

torna all’indice

40
Bocchi Cinzia 03/01/2015

Prima alternativa corretta

SELECT H.nome, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel AND S.tipo = ‘singola’
GROUP BY H.codHotel, H.nome

I passi da 1 a 5 sono identici alla soluzione principale.

passo 6  Viene effettuata la proiezione sui campi della select.

nome PrezzoMinimo PrezzoMassimo


Miramare 60 65
Marittimo 60 95
La baita 100 200
Miramare 150 300
Fiesta 100 100
Fiesta 100 180

torna all’indice

Seconda alternativa corretta

SELECT S.codHotel, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM stanza S
WHERE S.tipo = ‘singola’
GROUP BY S.codHotel

L’alternativa è utile nel caso non interessi il nome dell’hotel.

passo 1  Viene applicata la condizione where S.tipo = ‘singola’: le righe relative a


stanze con tipologia diversa vengono eliminate

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
3 100 singola 65,00 0
1 110 singola 60,00 1
3 110 singola 95,00 0
1 120 singola 100,00 1
3 120 singola 150,00 0
4 120 singola 200,00 1
41
Bocchi Cinzia 03/01/2015

22 130 singola 300,00 0


25 130 singola 150,00 0
58 140 singola 100,00 1
2 150 singola 180,00 0
3 150 singola 150,00 0
5 150 singola 160,00 1
7 150 singola 100,00 1

passo 2  Viene effettuato il raggruppamento sul campo codHotel della tabella stanza

numStanza codHotel ... prezzo ...


1 100 ... 60,00 ... gruppo 1: 100
3 100 ... 65,00
1 110 ... 60,00 ... gruppo 2: 110
3 110 ... 95,00 ...
1 120 ... 100,00 ...
3 120 ... 150,00 ... gruppo 3: 120
4 120 ... 200,00 ...
22 130 ... 300,00 ... gruppo 4: 130
25 130 ... 150,00 ...

58 140 ... 100,00 ... gruppo 5: 140

2 150 ... 180,00 ...


3 150 ... 150,00 ... gruppo 6: 150
5 150 ... 160,00 ...
7 150 ... 100,00 ...

passo 3  Vengono eseguite le funzioni MIN e MAX presenti nella select, per ciascun
gruppo.

numStanza codHotel ... prezzo ...


1 100 ... 60,00 ... gruppo 1: 100 min=60 max=65
3 100 ... 65,00
1 110 ... 60,00 ... gruppo 2: 110 min=60 max=95
3 110 ... 95,00 ...
1 120 ... 100,00 ...
3 120 ... 150,00 ... gruppo 3: 120 min=100 max=200
4 120 ... 200,00 ...
22 130 ... 300,00 ... gruppo 4: 130 min=150 max=300
25 130 ... 150,00 ...

58 140 ... 100,00 ... gruppo 5: 140 min=100 max=100

2 150 ... 180,00 ...


3 150 ... 150,00 ... gruppo 6: 150 min= 100 max=180
5 150 ... 160,00 ...
7 150 ... 100,00 ...

42
Bocchi Cinzia 03/01/2015

passo 4  Viene effettuata la proiezione sui campi della select.

codHotel PrezzoMinimo PrezzoMassimo


100 60 65
110 60 95
120 100 200
130 150 300
140 100 100
150 100 180

torna all’indice

Alternativa corretta solo in mancanza di hotel omonimi

SELECT H.nome, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel AND S.tipo = ‘singola’
GROUP BY H.nome

I passi da 1 a 3 sono identici alla soluzione principale.

passo 4  Viene effettuato il raggruppamento sul campo nome della tabella hotel
(vedere i nomi colonne evidenziati in giallo).

codHotel nome ... ... prezzo ...


100 Miramare ... ... 60,00 ...
100 Miramare ... ... 65,00 ... gruppo 1: Miramare
130 Miramare ... ... 300,00 ...
130 Miramare ... ... 150,00 ...
110 Marittimo ... ... 60,00 ...
gruppo 2: Marittimo
110 Marittimo ... ... 95,00 ...
120 La baita ... ... 100,00 ...
120 La baita ... ... 150,00 ... gruppo 3: La baita
120 La baita ... ... 200,00 ...
140 Fiesta ... ... 100,00 ...
150 Fiesta ... ... 180,00 ...
150 Fiesta ... ... 150,00 ... gruppo 4: Fiesta
150 Fiesta ... ... 160,00 ...
150 Fiesta ... ... 100,00 ...

passo 5 Vengono eseguite le funzioni MIN e MAX presenti nella select, per ciascun
gruppo.

43
Bocchi Cinzia 03/01/2015

codHotel nome ... ... prezzo ...


100 Miramare ... ... 60,00 ...
100 Miramare ... ... 65,00 ... gruppo 1: Miramare min=60 max=300
130 Miramare ... ... 300,00 ...
130 Miramare ... ... 150,00 ...
110 Marittimo ... ... 60,00 ...
gruppo 2: Marittimo min=60 max=95
110 Marittimo ... ... 95,00 ...
120 La baita ... ... 100,00 ...
120 La baita ... ... 150,00 ... gruppo 3: La baita min=100 max=200
120 La baita ... ... 200,00 ...
140 Fiesta ... ... 100,00 ...
150 Fiesta ... ... 180,00 ...
150 Fiesta ... ... 150,00 ... gruppo 4: Fiesta min=100 max=180
150 Fiesta ... ... 160,00 ...
150 Fiesta ... ... 100,00 ...

passo 6  Viene effettuata la proiezione sui campi della select.

nome PrezzoMinimo PrezzoMassimo


Miramare 60 300
Marittimo 60 95
La baita 100 200
Fiesta 100 180

torna all’indice

Alternativa corretta, analoga all’alternativa 2, ma non ottimizzata

SELECT H.codHotel, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM hotel H, stanza S
WHERE H.codHotel = S.codHotel AND S.tipo = ‘singola’
GROUP BY H.codHotel

Il resultset fornisce le informazioni richieste, tuttavia viene effettuato del lavoro superfluo
per il prodotto cartesiano delle tabelle e l’equi-join. Se non serve il nome dell’hotel, è
sufficiente utilizzare la tabella stanza. Si veda la seconda alternativa corretta.

44
Bocchi Cinzia 03/01/2015

codHotel PrezzoMinimo PrezzoMassimo


100 60 65
110 60 95
120 100 200
130 150 300
140 100 100
150 100 180

torna all’indice

Prima alternativa errata

SELECT H.codHotel, H.nome, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo)


AS PrezzoMassimo
FROM stanza S, hotel H
GROUP BY H.codHotel, H.nome

Mancano l’equi join e la condizione che seleziona solo le stanze singole. Si lavora,
pertanto, sulla tabella derivata dal prodotto cartesiano delle tabelle in from, con record tra
loro non correlati. Il resultset ottenuto è errato.

torna all’indice

Seconda alternativa errata

SELECT S.codHotel, MIN(S.prezzo) AS PrezzoMinimo, MAX(S.prezzo) AS


PrezzoMassimo
FROM stanza S
GROUP BY S.codHotel
HAVING S.tipo = ‘singola’

passo 1  Viene effettuato il raggruppamento su campo codHotel della tabella stanza.

45
Bocchi Cinzia 03/01/2015

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
2 100 doppia 58,00 1 gruppo 1: 100
3 100 singola 65,00 0
4 100 doppia 61,00 1
1 110 singola 60,00 1
2 110 doppia 80,00 0 gruppo 2: 110
3 110 singola 95,00 0
1 120 singola 100,00 1
2 120 doppia 95,00 0
gruppo 3: 120
3 120 singola 150,00 0
4 120 singola 200,00 1
21 130 doppia 250,00 0
gruppo 4: 130
22 130 singola 300,00 0
25 130 singola 150,00 0
55 140 doppia 99,00 1 gruppo 5: 140
58 140 singola 100,00 1
1 150 doppia 250,00 0
2 150 singola 180,00 0
3 150 singola 150,00 0
4 150 doppia 250,00 1 gruppo 6: 150
5 150 singola 160,00 1
6 150 doppia 350,00 1
7 150 singola 100,00 1

passo 2  Vengono eseguite le funzioni MIN e MAX presenti in select, su ciascun


gruppo.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
2 100 doppia 58,00 1 gruppo 1: 100 min=58 max=65
3 100 singola 65,00 0
4 100 doppia 61,00 1
1 110 singola 60,00 1
2 110 doppia 80,00 0 gruppo 2: 110 min=60 max=95
3 110 singola 95,00 0
1 120 singola 100,00 1
2 120 doppia 95,00 0
gruppo 3: 120 min=95 max=200
3 120 singola 150,00 0
4 120 singola 200,00 1
21 130 doppia 250,00 0
gruppo 4: 130 min=150 max=300
22 130 singola 300,00 0
25 130 singola 150,00 0
55 140 doppia 99,00 1 gruppo 5: 140 min=99 max=100
58 140 singola 100,00 1
1 150 doppia 250,00 0
2 150 singola 180,00 0

46
Bocchi Cinzia 03/01/2015

3 150 singola 150,00 0


4 150 doppia 250,00 1 gruppo 6: 150 min=100 max=350
5 150 singola 160,00 1
6 150 doppia 350,00 1
7 150 singola 100,00 1

I valori di MIN e MAX sono errati perché comprendono stanze di tipologia diversa dalla
singola.

passo 3  Viene applicata a ciascun gruppo la condizione in having.


La condizione si riferisce ai valori di una colonna e non a un valore valido per l’intero
gruppo, come sono per esempio min e max. Di conseguenza non è possibile verificarla e
viene restituito un errore.

torna all’indice

47
Bocchi Cinzia 03/01/2015

5) Per ogni cliente (è sufficiente l’idCliente), trovare il numero di prenotazioni


effettuate in hotel di Rimini nell’anno 2013 (si consideri solo dataInizio)

SELECT P.idCliente, COUNT(*) AS NumeroPrenotazioni


FROM prenotazione P, hotel H
WHERE P.codHotel = H.codHotel AND H.citta = ‘Rimini’ AND P.datainizio
BETWEEN ‘2013-01-01’ AND ‘2013-12-31’
GROUP BY P.idCliente

passo 1  Viene eseguito il prodotto cartesiano delle tabelle prenotazione e hotel.

codHot nome citta numSt codHot idClient data Inizio dataFine


el anza el e
100 Miramare Rimini 1 100 2 2013-07-14 2013-07-20
100 Miramare Rimini 1 100 4 2013-08-10 2013-08-20
100 Miramare Rimini 2 110 1 2013-07-02 2013-07-09
100 Miramare Rimini 55 140 3 2013-08-20 2013-08-28
100 Miramare Rimini 3 100 4 2013-09-01 2013-09-18
100 Miramare Rimini 55 140 5 2013-09-12 2013-09-30
100 Miramare Rimini 58 140 6 2013-07-01 2013-07-15
100 Miramare Rimini 4 120 7 2014-05-10 2014-05-20
100 Miramare Rimini 22 130 1 2014-06-05 2014-06-15
100 Miramare Rimini 4 150 3 2015-03-01
100 Miramare Rimini 5 150 4 2015-03-15
100 Miramare Rimini 1 120 2 2015-05-20
100 Miramare Rimini 1 150 3 2015-07-12
100 Miramare Rimini 2 150 5 2015-07-20
100 Miramare Rimini 3 150 6 2015-07-15
100 Miramare Rimini 1 100 7 2015-07-13
100 Miramare Rimini 3 100 4 2015-07-19
100 Miramare Rimini 3 110 2 2015-07-11
110 Marittimo Rimini 1 100 2 2013-07-14 2013-07-20
110 Marittimo Rimini 1 100 4 2013-08-10 2013-08-20
110 Marittimo Rimini 2 110 1 2013-07-02 2013-07-09
110 Marittimo Rimini 55 140 3 2013-08-20 2013-08-28
110 Marittimo Rimini 3 100 4 2013-09-01 2013-09-18
110 Marittimo Rimini 55 140 5 2013-09-12 2013-09-30
110 Marittimo Rimini 58 140 6 2013-07-01 2013-07-15
110 Marittimo Rimini 4 120 7 2014-05-10 2014-05-20
110 Marittimo Rimini 22 130 1 2014-06-05 2014-06-15
110 Marittimo Rimini 4 150 3 2015-03-01
110 Marittimo Rimini 5 150 4 2015-03-15
110 Marittimo Rimini 1 120 2 2015-05-20
110 Marittimo Rimini 1 150 3 2015-07-12
110 Marittimo Rimini 2 150 5 2015-07-20
110 Marittimo Rimini 3 150 6 2015-07-15
48
Bocchi Cinzia 03/01/2015

110 Marittimo Rimini 1 100 7 2015-07-13


110 Marittimo Rimini 3 100 4 2015-07-19
110 Marittimo Rimini 3 110 2 2015-07-11
120 La baita Aosta 1 100 2 2013-07-14 2013-07-20
120 La baita Aosta 1 100 4 2013-08-10 2013-08-20
120 La baita Aosta 2 110 1 2013-07-02 2013-07-09
120 La baita Aosta 55 140 3 2013-08-20 2013-08-28
120 La baita Aosta 3 100 4 2013-09-01 2013-09-18
120 La baita Aosta 55 140 5 2013-09-12 2013-09-30
120 La baita Aosta 58 140 6 2013-07-01 2013-07-15
120 La baita Aosta 4 120 7 2014-05-10 2014-05-20
120 La baita Aosta 22 130 1 2014-06-05 2014-06-15
120 La baita Aosta 4 150 3 2015-03-01
120 La baita Aosta 5 150 4 2015-03-15
120 La baita Aosta 1 120 2 2015-05-20
120 La baita Aosta 1 150 3 2015-07-12
120 La baita Aosta 2 150 5 2015-07-20
120 La baita Aosta 3 150 6 2015-07-15
120 La baita Aosta 1 100 7 2015-07-13
120 La baita Aosta 3 100 4 2015-07-19
120 La baita Aosta 3 110 2 2015-07-11
130 Miramare Napoli 1 100 2 2013-07-14 2013-07-20
130 Miramare Napoli 1 100 4 2013-08-10 2013-08-20
130 Miramare Napoli 2 110 1 2013-07-02 2013-07-09
130 Miramare Napoli 55 140 3 2013-08-20 2013-08-28
130 Miramare Napoli 3 100 4 2013-09-01 2013-09-18
130 Miramare Napoli 55 140 5 2013-09-12 2013-09-30
130 Miramare Napoli 58 140 6 2013-07-01 2013-07-15
130 Miramare Napoli 4 120 7 2014-05-10 2014-05-20
130 Miramare Napoli 22 130 1 2014-06-05 2014-06-15
130 Miramare Napoli 4 150 3 2015-03-01
130 Miramare Napoli 5 150 4 2015-03-15
130 Miramare Napoli 1 120 2 2015-05-20
130 Miramare Napoli 1 150 3 2015-07-12
130 Miramare Napoli 2 150 5 2015-07-20
130 Miramare Napoli 3 150 6 2015-07-15
130 Miramare Napoli 1 100 7 2015-07-13
130 Miramare Napoli 3 100 4 2015-07-19
130 Miramare Napoli 3 110 2 2015-07-11
140 Fiesta Rimini 1 100 2 2013-07-14 2013-07-20
140 Fiesta Rimini 1 100 4 2013-08-10 2013-08-20
140 Fiesta Rimini 2 110 1 2013-07-02 2013-07-09
140 Fiesta Rimini 55 140 3 2013-08-20 2013-08-28
140 Fiesta Rimini 3 100 4 2013-09-01 2013-09-18
140 Fiesta Rimini 55 140 5 2013-09-12 2013-09-30
140 Fiesta Rimini 58 140 6 2013-07-01 2013-07-15
140 Fiesta Rimini 4 120 7 2014-05-10 2014-05-20
140 Fiesta Rimini 22 130 1 2014-06-05 2014-06-15
140 Fiesta Rimini 4 150 3 2015-03-01
49
Bocchi Cinzia 03/01/2015

140 Fiesta Rimini 5 150 4 2015-03-15


140 Fiesta Rimini 1 120 2 2015-05-20
140 Fiesta Rimini 1 150 3 2015-07-12
140 Fiesta Rimini 2 150 5 2015-07-20
140 Fiesta Rimini 3 150 6 2015-07-15
140 Fiesta Rimini 1 100 7 2015-07-13
140 Fiesta Rimini 3 100 4 2015-07-19
140 Fiesta Rimini 3 110 2 2015-07-11
150 Fiesta Torino 1 100 2 2013-07-14 2013-07-20
150 Fiesta Torino 1 100 4 2013-08-10 2013-08-20
150 Fiesta Torino 2 110 1 2013-07-02 2013-07-09
150 Fiesta Torino 55 140 3 2013-08-20 2013-08-28
150 Fiesta Torino 3 100 4 2013-09-01 2013-09-18
150 Fiesta Torino 55 140 5 2013-09-12 2013-09-30
150 Fiesta Torino 58 140 6 2013-07-01 2013-07-15
150 Fiesta Torino 4 120 7 2014-05-10 2014-05-20
150 Fiesta Torino 22 130 1 2014-06-05 2014-06-15
150 Fiesta Torino 4 150 3 2015-03-01
150 Fiesta Torino 5 150 4 2015-03-15
150 Fiesta Torino 1 120 2 2015-05-20
150 Fiesta Torino 1 150 3 2015-07-12
150 Fiesta Torino 2 150 5 2015-07-20
150 Fiesta Torino 3 150 6 2015-07-15
150 Fiesta Torino 1 100 7 2015-07-13
150 Fiesta Torino 3 100 4 2015-07-19
150 Fiesta Torino 3 110 2 2015-07-11

passo 2  Viene applicata la condizione di equi join: P.codHotel = H.codHotel: le righe


con record non correlati vengono eliminate.

codHot nome citta numSt codHot idClient data Inizio dataFine


el anza el e
100 Miramare Rimini 1 100 2 2013-07-14 2013-07-20
100 Miramare Rimini 1 100 4 2013-08-10 2013-08-20
100 Miramare Rimini 3 100 4 2013-09-01 2013-09-18
100 Miramare Rimini 1 100 7 2015-07-13
100 Miramare Rimini 3 100 4 2015-07-19
110 Marittimo Rimini 2 110 1 2013-07-02 2013-07-09
110 Marittimo Rimini 3 110 2 2015-07-11
120 La baita Aosta 4 120 7 2014-05-10 2014-05-20
120 La baita Aosta 1 120 2 2015-05-20
120 La baita Aosta 3 110 2 2015-07-11
130 Miramare Napoli 22 130 1 2014-06-05 2014-06-15
140 Fiesta Rimini 55 140 3 2013-08-20 2013-08-28
140 Fiesta Rimini 55 140 5 2013-09-12 2013-09-30
140 Fiesta Rimini 58 140 6 2013-07-01 2013-07-15
150 Fiesta Torino 4 150 3 2015-03-01
150 Fiesta Torino 5 150 4 2015-03-15

50
Bocchi Cinzia 03/01/2015

150 Fiesta Torino 1 150 3 2015-07-12


150 Fiesta Torino 2 150 5 2015-07-20
150 Fiesta Torino 3 150 6 2015-07-15

passo 3  Viene applicata la condizione where H.citta = ‘Rimini’: tutte gli hotel che non
sono di Rimini vengono eliminati.

codHot nome citta numSt codHot idClient data Inizio dataFine


el anza el e
100 Miramare Rimini 1 100 2 2013-07-14 2013-07-20
100 Miramare Rimini 1 100 4 2013-08-10 2013-08-20
100 Miramare Rimini 3 100 4 2013-09-01 2013-09-18
100 Miramare Rimini 1 100 7 2015-07-13
100 Miramare Rimini 3 100 4 2015-07-19
110 Marittimo Rimini 2 110 1 2013-07-02 2013-07-09
110 Marittimo Rimini 3 110 2 2015-07-11
140 Fiesta Rimini 55 140 3 2013-08-20 2013-08-28
140 Fiesta Rimini 55 140 5 2013-09-12 2013-09-30
140 Fiesta Rimini 58 140 6 2013-07-01 2013-07-15

passo 4  Viene applicata la condizione where P.datainizio BETWEEN ‘2013-01-01’


AND ‘2013-12-31’: tutte le righe che non soddisfano la condizione vengono eliminate.

codHot nome citta numSt codHot idClient data Inizio dataFine


el anza el e
100 Miramare Rimini 1 100 4 2013-08-10 2013-08-20
100 Miramare Rimini 3 100 4 2013-09-01 2013-09-18
110 Marittimo Rimini 2 110 1 2013-07-02 2013-07-09
140 Fiesta Rimini 55 140 3 2013-08-20 2013-08-28
140 Fiesta Rimini 55 140 5 2013-09-12 2013-09-30
140 Fiesta Rimini 58 140 6 2013-07-01 2013-07-15

passo 5  Viene eseguito il raggruppamento sul campo idCliente della tabella


prenotazione.

51
Bocchi Cinzia 03/01/2015

codHotel ... ... idCliente ...


100 ... ... 4 ... gruppo 1 idCliente 4
100 ... ... 4 ...

110 ... ... 1 ... gruppo 2 idCliente 1

140 ... ... 3 ... gruppo 3 idCliente 3

140 ... ... 5 ... gruppo 4 idCliente 5

140 ... ... 6 ... gruppo 5 idCliente 6

passo 6  Viene eseguita la funzione COUNT presente in select, su ciascun gruppo.

codHotel ... ... idCliente ...


100 ... ... 4 ...
gruppo 1 idCliente 4 count=2
100 ... ... 4 ...

110 ... ... 1 ... gruppo 2 idCliente 1 count=1

140 ... ... 3 ... gruppo 3 idCliente 3 count=1

140 ... ... 5 ... gruppo 4 idCliente 5 count=1

140 ... ... 6 ... gruppo 5 idCliente 6 count=1

passo 7  Vengono proiettati i campi presenti in select.

idCliente NumeroPrenotazioni
4 2
1 1
3 1
5 1
6 1

torna all’indice

52
Bocchi Cinzia 03/01/2015

Alternativa analoga alla soluzione principale ma non ottimizzata

SELECT P.idCliente, COUNT(*) AS NumeroPrenotazioni


FROM prenotazione P, hotel H, stanza S
WHERE P.codHotel = S.codHotel AND S.codHotel = H.codHotel AND H.citta =
‘Rimini’ AND P.datainizio BETWEEN ‘2013-01-01’ AND ‘2013-12-31’
GROUP BY P.idCliente

La tabella stanza è superflua ma costringe il sistema ad effettuare molto lavoro aggiuntivo


per ottenere la stessa soluzione.

torna all’indice

Alternativa errata

SELECT P.idCliente
FROM prenotazione P, hotel H
WHERE P.codHotel = H.codHotel AND H.citta = ‘Rimini’ AND P.datainizio
BETWEEN ‘2013-01-01’ AND ‘2013-12-31’
GROUP BY P.idCliente

Manca la funzione di aggregazione COUNT. Si ottiene quindi un risultato diverso da quello


atteso.

idCliente
4
1
3
5
6

torna all’indice

53
Bocchi Cinzia 03/01/2015

6) Trovare il prezzo medio delle stanze, suddivise per tipologia, ma solo se il


numero di stanze per tipologia è superiore a 100

SELECT S.tipo, AVG(S.prezzo) AS PrezzoMedio


FROM stanza S
GROUP BY S.tipo
HAVING COUNT(*) > 100

passo 1  Viene effettuato il raggruppamento sul campo tipo della tabella stanza.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
3 100 singola 65,00 0
1 110 singola 60,00 1
3 110 singola 95,00 0
1 120 singola 100,00 1
3 120 singola 150,00 0
4 120 singola 200,00 1 gruppo 1 singola
22 130 singola 300,00 0
25 130 singola 150,00 0
58 140 singola 100,00 1
2 150 singola 180,00 0
3 150 singola 150,00 0
5 150 singola 160,00 1
7 150 singola 100,00 1
2 100 doppia 58,00 1
4 100 doppia 61,00 1
2 110 doppia 80,00 0
2 120 doppia 95,00 0
21 130 doppia 250,00 0 gruppo 2 doppia
55 140 doppia 99,00 1
1 150 doppia 250,00 0
4 150 doppia 250,00 1
6 150 doppia 350,00 1

passo 2  Viene eseguita la funzione AVG presente in select, su ciascun gruppo.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
3 100 singola 65,00 0
1 110 singola 60,00 1
3 110 singola 95,00 0
1 120 singola 100,00 1
3 120 singola 150,00 0
4 120 singola 200,00 1 gruppo 1 singola avg=133,57
22 130 singola 300,00 0
54
Bocchi Cinzia 03/01/2015

25 130 singola 150,00 0


58 140 singola 100,00 1
2 150 singola 180,00 0
3 150 singola 150,00 0
5 150 singola 160,00 1
7 150 singola 100,00 1
2 100 doppia 58,00 1
4 100 doppia 61,00 1
2 110 doppia 80,00 0
2 120 doppia 95,00 0
21 130 doppia 250,00 0 gruppo 2 doppia avg=165,89
55 140 doppia 99,00 1
1 150 doppia 250,00 0
4 150 doppia 250,00 1
6 150 doppia 350,00 1

passo 3  Viene eseguita la funzione COUNT presente in having, per ciascun gruppo.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
3 100 singola 65,00 0
1 110 singola 60,00 1
3 110 singola 95,00 0
1 120 singola 100,00 1
3 120 singola 150,00 0
4 120 singola 200,00 1 gruppo 1 singola avg=133,57 count=14
22 130 singola 300,00 0
25 130 singola 150,00 0
58 140 singola 100,00 1
2 150 singola 180,00 0
3 150 singola 150,00 0
5 150 singola 160,00 1
7 150 singola 100,00 1
2 100 doppia 58,00 1
4 100 doppia 61,00 1
2 110 doppia 80,00 0
2 120 doppia 95,00 0
21 130 doppia 250,00 0 gruppo 2 doppia avg=165,89 count=9
55 140 doppia 99,00 1
1 150 doppia 250,00 0
4 150 doppia 250,00 1
6 150 doppia 350,00 1

passo 4  Viene applicata la condizione in having COUNT(*) > 100, a ciascun gruppo.
Nessuno dei due gruppi ha un valore di count superiore a 100 perché , per evidenti motivi,
le tabelle di esempio fornite hanno un numero limitato di record. Quindi, per ciò che
rifuarda l’esempio, il result set sarebbe vuoto. Tuttavia, per comprendere il significato della

55
Bocchi Cinzia 03/01/2015

clausola having, supponiamo che la condizione sia COUNT(*) >9. Solo il gruppo 1
soddisfa la condizione e il gruppo 2 viene escluso.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
3 100 singola 65,00 0
1 110 singola 60,00 1
3 110 singola 95,00 0
1 120 singola 100,00 1
3 120 singola 150,00 0
4 120 singola 200,00 1 gruppo 1 singola avg=133,57 count=14
22 130 singola 300,00 0
25 130 singola 150,00 0
58 140 singola 100,00 1
2 150 singola 180,00 0
3 150 singola 150,00 0
5 150 singola 160,00 1
7 150 singola 100,00 1

passo 5  Vengono proiettati gli attributi in select.

tipo PrezzoMedio
singola 133,57

torna all’indice

Prima alternativa errata

SELECT S.tipo, AVG(S.prezzo) AS PrezzoMedio


FROM stanza S
GROUP BY S.tipo
HAVING S.tipo > 100

I passi da 1 a 3 sono identici alla soluzione principale.

passo 4  Viene applicata la condizione in having S.tipo > 100, a ciascun gruppo.
Tuttavia l’attributo tipo non è relativo a un gruppo ma a ogni singolo record della tabella e,
di conseguenza la condizione non può essere valutata. La query restituisce un errore.

torna all’indice

56
Bocchi Cinzia 03/01/2015

Seconda alternativa errata

SELECT S.tipo, S.codHotel, COUNT(*) AS NumStanze, AVG(S.prezzo) AS


PrezzoMedio
FROM stanza S
GROUP BY S.tipo, S.codHotel
HAVING NumStanze > 100

passo 1  Viene effettuato il raggruppamento sui campi tipo e codHotel della tabella
stanza.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
gruppo 1 100 singola
3 100 singola 65,00 0
2 100 doppia 58,00 1
4 100 doppia 61,00 1 gruppo 2 100 doppia
1 110 singola 60,00 1
gruppo 3 110 singola
3 110 singola 95,00 0
2 110 doppia 80,00 0 gruppo 4 110 doppia
1 120 singola 100,00 1
3 120 singola 150,00 0 gruppo 5 120 singola
4 120 singola 200,00 1
2 120 doppia 95,00 0 gruppo 6 120 doppia
22 130 singola 300,00 0 gruppo 7 130 singola
25 130 singola 150,00 0
21 130 doppia 250,00 0 gruppo 8 130 doppia
58 140 singola 100,00 1 gruppo 9 140 singola
55 140 doppia 99,00 1 gruppo 10 140 doppia
2 150 singola 180,00 0
3 150 singola 150,00 0
5 150 singola 160,00 1 gruppo 11 150 singola
7 150 singola 100,00 1
1 150 doppia 250,00 0
4 150 doppia 250,00 1 gruppo 12 150 doppia
6 150 doppia 350,00 1

passo 2  Viene eseguita la funzione COUNT presente in select, su ciascun gruppo.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
gruppo 1 100 singola count=2
3 100 singola 65,00 0
2 100 doppia 58,00 1
4 100 doppia 61,00 1 gruppo 2 100 doppia count=2
1 110 singola 60,00 1
gruppo 3 110 singola count=2
3 110 singola 95,00 0
2 110 doppia 80,00 0 gruppo 4 110 doppia count=1
1 120 singola 100,00 1
gruppo 5 120 singola count=3
57
Bocchi Cinzia 03/01/2015

3 120 singola 150,00 0


4 120 singola 200,00 1
2 120 doppia 95,00 0 gruppo 6 120 doppia count=1
22 130 singola 300,00 0 gruppo 7 130 singola count=2
25 130 singola 150,00 0
21 130 doppia 250,00 0 gruppo 8 130 doppia count=1
58 140 singola 100,00 1 gruppo 9 140 singola count=1
55 140 doppia 99,00 1 gruppo 10 140 doppia count=1
2 150 singola 180,00 0
3 150 singola 150,00 0
5 150 singola 160,00 1 gruppo 11 150 singola count=4
7 150 singola 100,00 1
1 150 doppia 250,00 0
4 150 doppia 250,00 1 gruppo 12 150 doppia count=3
6 150 doppia 350,00 1

passo 3  Viene eseguita la funzione AVG presente in select, su ciascun gruppo.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
gruppo 1 100 singola count=2 avg=62,5
3 100 singola 65,00 0
2 100 doppia 58,00 1
4 100 doppia 61,00 1 gruppo 2 100 doppia count=2 avg=59,5
1 110 singola 60,00 1
gruppo 3 110 singola count=2 avg=77,5
3 110 singola 95,00 0
2 110 doppia 80,00 0 gruppo 4 110 doppia count=1 avg=80
1 120 singola 100,00 1
3 120 singola 150,00 0 gruppo 5 120 singola count=3 avg=150
4 120 singola 200,00 1
2 120 doppia 95,00 0 gruppo 6 120 doppia count=1 avg=95
22 130 singola 300,00 0 gruppo 7 130 singola count=2 avg=225
25 130 singola 150,00 0
21 130 doppia 250,00 0 gruppo 8 130 doppia count=1 avg=250
58 140 singola 100,00 1 gruppo 9 140 singola count=1 avg=100
55 140 doppia 99,00 1 gruppo 10 140 doppia count=1 avg=99
2 150 singola 180,00 0
3 150 singola 150,00 0
5 150 singola 160,00 1 gruppo 11 150 singola count=4 avg=147,5
7 150 singola 100,00 1
1 150 doppia 250,00 0
4 150 doppia 250,00 1 gruppo 12 150 doppia count=3 avg=283,3
6 150 doppia 350,00 1

passo 4  Viene applicata la condizione presente in having NumStanze > 100, cioè
COUNT(*)>100, a ciascun gruppo. Nessun gruppo soddisfa la condizione, ma
supponiamo che essa sia NumStanze > 2. Tutti i gruppi che non soddisfano tale
condizione vengono eliminati.

58
Bocchi Cinzia 03/01/2015

numStanza codHotel tipo prezzo occupata


1 120 singola 100,00 1
3 120 singola 150,00 0 gruppo 5 120 singola count=3 avg=150
4 120 singola 200,00 1
2 150 singola 180,00 0
3 150 singola 150,00 0
gruppo 11 150 singola count=4 avg=147,5
5 150 singola 160,00 1
7 150 singola 100,00 1
1 150 doppia 250,00 0
4 150 doppia 250,00 1 gruppo 12 150 doppia count=3 avg=283,3
6 150 doppia 350,00 1

passo 5  Vengono proiettati gli attributi in select.

tipo codHotel NumStanze PrezzoMedio


singola 120 3 150
singola 150 4 147,5
doppia 150 3 283,3

La query non genera errori ma il risultato ottenuto è ben diverso da quello richiesto.

torna all’indice

59
Bocchi Cinzia 03/01/2015

Terza alternativa errata

SELECT S.numStanza, COUNT(*) AS NumStanze, AVG(S.prezzo) AS PrezzoMedio


FROM stanza S
GROUP BY S.numStanza
HAVING NumStanze > 100

passo 1  Viene eseguito il raggruppamento sul campo numStanza della tabella stanza.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
1 110 singola 60,00 1
gruppo 1 numstanza 1
1 120 singola 100,00 1
1 150 doppia 250,00 0
2 100 doppia 58,00 1
2 110 doppia 80,00 0 gruppo 2 numstanza 2
2 120 doppia 95,00 0
2 150 singola 180,00 0
3 100 singola 65,00 0
3 110 singola 95,00 0 gruppo 3 numstanza 3
3 120 singola 150,00 0
3 150 singola 150,00 0
4 100 doppia 61,00 1
gruppo 4 numstanza 4
4 120 singola 200,00 1
4 150 doppia 250,00 1
5 150 singola 160,00 1 gruppo 5 numstanza 5

6 150 doppia 350,00 1 gruppo 6 numstanza 6

7 150 singola 100,00 1 gruppo 7 numstanza 7

21 130 doppia 250,00 0 gruppo 8 numstanza 21

22 130 singola 300,00 0


gruppo 9 numstanza 22

25 130 singola 150,00 0


gruppo 10 numstanza 25

55 140 doppia 99,00 1


gruppo 11 numstanza 55

58 140 singola 100,00 1


gruppo 12 numstanza 58

passo 2  Viene eseguita la funzione COUNT presente in select, su ciascun gruppo.

60
Bocchi Cinzia 03/01/2015

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
1 110 singola 60,00 1
gruppo 1 numstanza 1 count=4
1 120 singola 100,00 1
1 150 doppia 250,00 0
2 100 doppia 58,00 1
2 110 doppia 80,00 0 gruppo 2 numstanza 2 count=4
2 120 doppia 95,00 0
2 150 singola 180,00 0
3 100 singola 65,00 0
3 110 singola 95,00 0 gruppo 3 numstanza 3 count=4
3 120 singola 150,00 0
3 150 singola 150,00 0
4 100 doppia 61,00 1
gruppo 4 numstanza 4 count=3
4 120 singola 200,00 1
4 150 doppia 250,00 1
5 150 singola 160,00 1 gruppo 5 numstanza 5 count=1

6 150 doppia 350,00 1 gruppo 6 numstanza 6 count=1

7 150 singola 100,00 1 gruppo 7 numstanza 7 count=1

21 130 doppia 250,00 0 gruppo 8 numstanza 21 count=1

22 130 singola 300,00 0


gruppo 9 numstanza 22 count=1

25 130 singola 150,00 0


gruppo 10 numstanza 25 count=1

55 140 doppia 99,00 1


gruppo 11 numstanza 55 count=1

58 140 singola 100,00 1


gruppo 12 numstanza 58 count=1

passo 3  Viene eseguita la funzione AVG presente in select, su ciascun gruppo.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
1 110 singola 60,00 1
gruppo 1 numst 1 count=4 avg=117,5
1 120 singola 100,00 1
1 150 doppia 250,00 0
2 100 doppia 58,00 1
2 110 doppia 80,00 0 gruppo 2 numst 2 count=4 avg=103,25
2 120 doppia 95,00 0
2 150 singola 180,00 0
3 100 singola 65,00 0
3 110 singola 95,00 0 gruppo 3 numst 3 count=4 avg=115
3 120 singola 150,00 0
3 150 singola 150,00 0
61
Bocchi Cinzia 03/01/2015

4 100 doppia 61,00 1


gruppo 4 numst 4 count=3 avg= 170,3
4 120 singola 200,00 1
4 150 doppia 250,00 1
5 150 singola 160,00 1 gruppo 5 numst 5 count=1 avg=160

6 150 doppia 350,00 1 gruppo 6 numst 6 count=1 avg=350

7 150 singola 100,00 1 gruppo 7 numst 7 count=1 avg=100

21 130 doppia 250,00 0 gruppo 8 numst 21 count=1 avg=250

22 130 singola 300,00 0


gruppo 9 numst 22 count=1 avg=300

25 130 singola 150,00 0


gruppo 10 numst 25 count=1 avg=150

55 140 doppia 99,00 1


gruppo 11 numst 55 count=1 avg=99

58 140 singola 100,00 1


gruppo 12 numst 58 count=1 avg=100

passo 4  Viene applicata la condizione presente in having NumStanze > 100, cioè
COUNT(*)>100, a ciascun gruppo. Nessun gruppo soddisfa la condizione, ma
supponiamo che essa sia NumStanze > 2. Tutti i gruppi che non soddisfano tale
condizione vengono eliminati.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
1 110 singola 60,00 1
gruppo 1 numst 1 count=4 avg=117,5
1 120 singola 100,00 1
1 150 doppia 250,00 0
2 100 doppia 58,00 1
2 110 doppia 80,00 0 gruppo 2 numst 2 count=4 avg=103,25
2 120 doppia 95,00 0
2 150 singola 180,00 0
3 100 singola 65,00 0
3 110 singola 95,00 0 gruppo 3 numst 3 count=4 avg=115
3 120 singola 150,00 0
3 150 singola 150,00 0
4 100 doppia 61,00 1
gruppo 4 numst 4 count=3 avg= 170,3
4 120 singola 200,00 1
4 150 doppia 250,00 1

passo 5  Vengono proiettati gli attributi in select.

62
Bocchi Cinzia 03/01/2015

numStanza NumStanze PrezzoMedio


1 4 117,5
2 4 103,25
3 4 115
4 3 170,3

La query non genera errori ma il risultato ottenuto è ben diverso da quello richiesto.

torna all’indice

Quarta alternativa errata

SELECT S.tipo, AVG(S.prezzo) AS PrezzoMedio


FROM stanza S
GROUP BY S.tipo
HAVING numStanza > 100

I passi da 1 a 3 sono identici alla soluzione principale.

passo 4  Viene applicata la condizione in having numStanza > 100, a ciascun gruppo.
Tuttavia l’attributo tipo non è relativo a un gruppo ma a ogni singolo record della tabella e,
di conseguenza la condizione non può essere valutata. La query restituisce un errore.

torna all’indice

Quinta alternativa errata

SELECT AVG(S.prezzo) AS PrezzoMedio, COUNT(S.tipo)


FROM stanza S
GROUP BY S.tipo
HAVING COUNT(S.tipo) >= 100

I passi da 1 a 3 sono identici alla soluzione principale e producono la seguente tabella.

numStanza codHotel tipo prezzo occupata


1 100 singola 60,00 1
3 100 singola 65,00 0
1 110 singola 60,00 1

63
Bocchi Cinzia 03/01/2015

3 110 singola 95,00 0


1 120 singola 100,00 1
3 120 singola 150,00 0
4 120 singola 200,00 1 gruppo 1 singola avg=133,57 count=14
22 130 singola 300,00 0
25 130 singola 150,00 0
58 140 singola 100,00 1
2 150 singola 180,00 0
3 150 singola 150,00 0
5 150 singola 160,00 1
7 150 singola 100,00 1
2 100 doppia 58,00 1
4 100 doppia 61,00 1
2 110 doppia 80,00 0
2 120 doppia 95,00 0
21 130 doppia 250,00 0 gruppo 2 doppia avg=165,89 count=9
55 140 doppia 99,00 1
1 150 doppia 250,00 0
4 150 doppia 250,00 1
6 150 doppia 350,00 1

passo 4  Viene applicata a ciascun gruppo la condizione presente in having


COUNT(S.tipo) >= 100, che è sbagliata perché comprende anche il valore 100, che
doveva essere escluso. Per i motivi esposti in precedenza, supponiamo che la condizione
sia COUNT(S.tipo) >= 9. Entrambi i gruppi soddisfano tale condizione (a differenza della
soluzione principale, dove non è presente l’uguale).

passo 5  Vengono proiettati gli attributi in select.

PrezzoMedio COUNT(S.tipo)
133,57 14
165,89 9

La query non genera errori, ma i risultati ottenuti non sono interpretabili perché non si sa a
che cosa si riferiscono i dati contenuti nelle due colonne.

torna all’indice

64
Bocchi Cinzia 03/01/2015

7) Per ogni hotel (è sufficiente conoscere il codHotel) determinare il numero di


prenotazioni effettuate prima del 10-07-2015 (si utilizzi dataInizio), unicamente
nel caso tale numero sia superiore a 10

SELECT P.codHotel, COUNT(*) AS NumeroPrenotazioni


FROM prenotazione P
WHERE P.dataInizio < ‘2015-07-10’
GROUP BY P.codHotel
HAVING NumeroPrenotazioni > 10

passo 1  Viene applicata la condizione where dataInizio < ‘2015-07-10’ alla tabella
prenotazione.

numStanza codHotel idCliente data Inizio dataFine


1 100 2 2013-07-14 2013-07-20
1 100 4 2013-08-10 2013-08-20
2 110 1 2013-07-02 2013-07-09
55 140 3 2013-08-20 2013-08-28
3 100 4 2013-09-01 2013-09-18
55 140 5 2013-09-12 2013-09-30
58 140 6 2013-07-01 2013-07-15
4 120 7 2014-05-10 2014-05-20
22 130 1 2014-06-05 2014-06-15
4 150 3 2015-03-01
5 150 4 2015-03-15
1 120 2 2015-05-20

passo 2  Viene eseguito il raggruppamento sul campo codHotel della tabella


prenotazione.

... codHotel ... data Inizio ...


... 100 ... 2013-07-14 ...
gruppo 1 codH 100
... 100 ... 2013-08-10 ...
... 100 ... 2013-09-01 ...
... 110 ... 2013-07-02 ... gruppo 2 codH 110

... 120 ... 2014-05-10 ... gruppo 3 codH 120


... 120 ... 2015-05-20 ...
... 130 ... 2014-06-05 ...
gruppo 4 codH 130

... 140 ... 2013-08-20 ...


... 140 ... 2013-09-12 ... gruppo 5 codH 140
... 140 ... 2013-07-01 ...
... 150 ... 2015-03-01 ... gruppo 6 codH 150
... 150 ... 2015-03-15 ...

65
Bocchi Cinzia 03/01/2015

passo 3  Viene eseguita, su ciascun gruppo, la funzione COUNT presente in select.

... codHotel ... data Inizio ...


... 100 ... 2013-07-14 ...
gruppo 1 codH 100 count=3
... 100 ... 2013-08-10 ...
... 100 ... 2013-09-01 ...
... 110 ... 2013-07-02 ... gruppo 2 codH 110 count=1

... 120 ... 2014-05-10 ... gruppo 3 codH 120 count=2


... 120 ... 2015-05-20 ...
... 130 ... 2014-06-05 ...
gruppo 4 codH 130 count=1

... 140 ... 2013-08-20 ...


... 140 ... 2013-09-12 ... gruppo 5 codH 140 count=3
... 140 ... 2013-07-01 ...
... 150 ... 2015-03-01 ... gruppo 6 codH 150 count=2
... 150 ... 2015-03-15 ...

passo 4  Viene applicata la condizione having NumeroPrenotazioni > 10: tutti i gruppi
il cui valore di count è minore o uguale a 10 vengono eliminati. Per ragioni già speigate in
precedenza, supponiamo che la condizione in having sia NumeroPrenotazioni > 1.

... codHotel ... data Inizio ...


... 100 ... 2013-07-14 ...
gruppo 1 codH 100 count=3
... 100 ... 2013-08-10 ...
... 100 ... 2013-09-01 ...
... 120 ... 2014-05-10 ... gruppo 3 codH 120 count=2
... 120 ... 2015-05-20 ...
... 140 ... 2013-08-20 ...
... 140 ... 2013-09-12 ... gruppo 5 codH 140 count=3
... 140 ... 2013-07-01 ...
... 150 ... 2015-03-01 ... gruppo 6 codH 150 count=2
... 150 ... 2015-03-15 ...

passo 5  Vengono proiettati gli attributi in select.

codHotel NumeroPrenotazioni
100 3
120 2
140 3
150 2

torna all’indice

66
Bocchi Cinzia 03/01/2015

Prima alternativa corretta ma non ottimizzata

SELECT H.codHotel, COUNT(*) AS NumeroPrenotazioni


FROM prenotazione P, hotel H
WHERE P.codHotel = H.codHotel AND P.dataInizio < ‘2015-07-10’
GROUP BY H.codHotel
HAVING NumeroPrenotazioni > 10

Il risultato è lo stesso della soluzione principale, con un carico di lavoro aggiuntivo dovuto
al prodotto cartesiano delle due tabelle e alla condizione di equi join.

codHotel NumeroPrenotazioni
100 3
120 2
140 3
150 2

torna all’indice

Seconda alternativa corretta ma non ottimizzata

SELECT S.codHotel, COUNT(*) AS NumeroPrenotazioni


FROM prenotazione P, stanza S
WHERE P.codHotel = S.codHotel AND P.dataInizio < ‘2015-07-10’
GROUP BY S.codHotel
HAVING NumeroPrenotazioni > 10

Il risultato è lo stesso della soluzione principale, con un carico di lavoro aggiuntivo dovuto
al prodotto cartesiano delle due tabelle e alla condizione di equi join.

codHotel NumeroPrenotazioni
100 3
120 2
140 3
150 2

torna all’indice

67
Bocchi Cinzia 03/01/2015

8) Per ogni città e per ogni hotel operante in tale città determinare il numero di
prenotazioni effettuate nel periodo 10-07-2015 e 20-07-2015 (si utilizzi dataInizio)
da clienti provenienti da Roma

SELECT H.citta, H.codHotel, COUNT(*) AS NumeroPrenotazioni


FROM prenotazione P, hotel H, cliente C
WHERE P.codHotel = H.codHotel AND P.idCliente = C.idCliente AND P.dataInizio
BETWEEN ‘2015-07-10’ AND ‘2015-07-20’ AND C.citta = ‘Roma’
GROUP BY H.citta, H.codHotel

passo 1  Viene eseguito il prodotto cartesiano tra le tre tabelle presenti in from. Vista la
quantità di dati, passerò subito a mostrare i risultati ottenuti al passo 2.

passo 2  Vengono applicate le condizioni di equi join: P.codHotel = H.codHotel AND


P.idCliente = C.idCliente.

... cod idC data Inizio ... cod nome citta idC ... città
Hote lien Hote lien
l te l te
... 100 2 2013-07-14 ... 100 Miramare Rimini 2 ... Milano
... 100 4 2013-08-10 ... 100 Miramare Rimini 4 ... Catania
... 110 1 2013-07-02 ... 110 Marittimo Rimini 1 ... Torino
... 140 3 2013-08-20 ... 140 Fiesta Rimini 3 ... Roma
... 100 4 2013-09-01 ... 100 Miramare Rimini 4 ... Catania
... 140 5 2013-09-12 ... 140 Fiesta Rimini 5 ... Roma
... 140 6 2013-07-01 ... 140 Fiesta Rimini 6 ... Roma
... 120 7 2014-05-10 ... 120 La baita Aosta 7 ... Roma
... 130 1 2014-06-05 ... 130 Miramare Napoli 1 ... Torino
... 150 3 2015-03-01 ... 150 Fiesta Torino 3 ... Roma
... 150 4 2015-03-15 ... 150 Fiesta Torino 4 ... Catania
... 120 2 2015-05-20 ... 120 La baita Aosta 2 ... Milano
... 150 3 2015-07-12 ... 150 Fiesta Torino 3 ... Roma
... 150 5 2015-07-20 ... 150 Fiesta Torino 5 ... Roma
... 150 6 2015-07-15 ... 150 Fiesta Torino 6 ... Roma
... 100 7 2015-07-13 ... 100 Miramare Rimini 7 ... Roma
... 100 4 2015-07-19 ... 100 Miramare Rimini 4 ... Catania
... 110 2 2015-07-11 ... 110 Marittimo Rimini 2 ... Milano

passo 3  Viene applicata la condizione P.dataInizio BETWEEN ‘2015-07-10’ AND


‘2015-07-20’. Tutte le righe che non la soddisfano, vengono eliminate.

... cod idC data Inizio ... cod nome citta idC ... città
Hote lien Hote lien
l te l te
... 150 3 2015-07-12 ... 150 Fiesta Torino 3 ... Roma
... 150 5 2015-07-20 ... 150 Fiesta Torino 5 ... Roma
... 150 6 2015-07-15 ... 150 Fiesta Torino 6 ... Roma
... 100 7 2015-07-13 ... 100 Miramare Rimini 7 ... Roma
... 100 4 2015-07-19 ... 100 Miramare Rimini 4 ... Catania
... 110 2 2015-07-11 ... 110 Marittimo Rimini 2 ... Milano

68
Bocchi Cinzia 03/01/2015

passo 4  viene applicata la condizione C.citta = ‘Roma’.

... cod idC data Inizio ... cod nome citta idC ... città
Hote lien Hote lien
l te l te
... 150 3 2015-07-12 ... 150 Fiesta Torino 3 ... Roma
... 150 5 2015-07-20 ... 150 Fiesta Torino 5 ... Roma
... 150 6 2015-07-15 ... 150 Fiesta Torino 6 ... Roma
... 100 7 2015-07-13 ... 100 Miramare Rimini 7 ... Roma

passo 5  Viene eseguito il raggruppamento sui campi citta e codHotel della tabella
hotel.

... cod nome citta ...


Hot
el
... 150 Fiesta Torino ...
... 150 Fiesta Torino ... gruppo 1 Fiesta Torino
... 150 Fiesta Torino ...
... 100 Miramare Rimini ...
gruppo 2 Miramare Rimini

passo 6  viene eseguita la funzione COUNT presente in select, su ciascun gruppo.

... cod nome citta ...


Hot
el
... 150 Fiesta Torino ...
... 150 Fiesta Torino ... gruppo 1 Fiesta Torino count=3
... 150 Fiesta Torino ...
... 100 Miramare Rimini ...
gruppo 2 Miramare Rimini count= 1

passo 7  Vengono proiettati i campi in select.

citta codHotel NumeroPrenotazioni


Torino 150 3
Rimini 100 1

torna all’indice

69
Bocchi Cinzia 03/01/2015

Alternativa corretta solo se non esistono hotel omonimi nella stessa città

SELECT H.citta, H.nome, COUNT(*) AS NumeroPrenotazioni


FROM prenotazione P, hotel H, cliente C
WHERE P.codHotel = H.codHotel AND P.idCliente = C.idCliente AND P.dataInizio
BETWEEN ‘2015-07-10’ AND ‘2015-07-20’ AND C.citta = ‘Roma’
GROUP BY H.citta, H.nome

Il resultset è uguale a quello restituito dalla soluzione principale, ma solo se non esistono
nella stessa città hotel con lo stesso nome.

torna all’indice

Alternativa corretta ma non ottimizzata

SELECT H.citta, H.codHotel, COUNT(*) AS NumeroPrenotazioni


FROM prenotazione P, hotel H, cliente C, stanza S
WHERE P.codHotel = S.codHotel AND S.codHotel = H.codHotel AND P.idCliente =
C.idCliente AND P.dataInizio BETWEEN ‘2015-07-10’ AND ‘2015-07-20’
AND C.citta = ‘Roma’
GROUP BY H.citta, H.codHotel

Il resultset è lo stesso che si ottiene con la soluzione principale, ma il lavoro svolto dal
sistema è più oneroso perché in from è stata inserita la tabella superflua stanza.

torna all’indice

Prima alternativa errata

SELECT H.citta, COUNT(*) AS NumeroPrenotazioni


FROM prenotazione P, hotel H, cliente C
WHERE P.codHotel = H.codHotel AND P.idCliente = C.idCliente AND P.dataInizio
BETWEEN ‘2015-07-10’ AND ‘2015-07-20’ AND C.citta = ‘Roma’
GROUP BY H.citta

Questa soluzione restituisce il numero di prenotazioni per ogni città e non distingue tra
prenotazioni fatti in hotel diversi della stessa città. La query viene eseguita ma restituisce
risultati diversi da quelli attesi.

torna all’indice

70
Bocchi Cinzia 03/01/2015

Seconda alternativa errata

SELECT H.citta, H.codHotel, COUNT(*) AS NumeroPrenotazioni


FROM prenotazione P, hotel H, cliente C
WHERE P.codHotel = H.codHotel AND P.idCliente = C.idCliente AND P.dataInizio
BETWEEN ‘2015-07-10’ AND ‘2015-07-20’ AND C.citta = ‘Roma’
GROUP BY H.citta

La query restituisce un errore perché il campo H.codHotel presente in select non è stato
riportato nella clausola group by.

torna all’indice

Quest'opera è stata rilasciata con licenza Creative Commons Attribuzione - Non commerciale - Condividi allo
stesso modo 3.0 Italia. Per leggere una copia della licenza visita il sito web
http://creativecommons.org/licenses/by-nc-sa/3.0/it/ o spedisci una lettera a Creative Commons, 171 Second
Street, Suite 300, San Francisco, California, 94105, USA.

71

Potrebbero piacerti anche