Sei sulla pagina 1di 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

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 allindice

Bocchi Cinzia 03/01/2015

LE TABELLE DI ESEMPIO
hotel
codHotel
100
110
120
130
140
150

stanza
numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7

nome
Miramare
Marittimo
La baita
Miramare
Fiesta
Fiesta

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

citta
Rimini
Rimini
Aosta
Napoli
Rimini
Torino

tipo
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1

Il prezzo di una stanza riferito ad una notte di pernottamento


Lattributo occupata assume valore 1 se la stanza occupata, 0 altrimenti

Bocchi Cinzia 03/01/2015

cliente
idCliente
1
2
3
4
5
6
7

nome
Rossi
Neri
Verdi
Rossi
Verdi
Bianchi
Marrone

prenotazione
numStanza
1
1
2
55
3
55
58
4
22
4
5
1
1
2
3
1
3
3

citt
Torino
Milano
Roma
Catania
Roma
Roma
Roma

codHotel
100
100
110
140
100
140
140
120
130
150
150
120
150
150
150
100
100
110

idCliente
2
4
1
3
4
5
6
7
1
3
4
2
3
5
6
7
4
2

data Inizio
2013-07-14
2013-08-10
2013-07-02
2013-08-20
2013-09-01
2013-09-12
2013-07-01
2014-05-10
2014-06-05
2015-03-01
2015-03-15
2015-05-20
2015-07-12
2015-07-20
2015-07-15
2015-07-13
2015-07-19
2015-07-11

dataFine
2013-07-20
2013-08-20
2013-07-09
2013-08-28
2013-09-18
2013-09-30
2013-07-15
2014-05-20
2014-06-15

Lattributo dataFine opzionale, cio pu non essere specificato

torna allindice

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 lidCliente), trovare il numero di prenotazioni effettuate in
hotel di Rimini nellanno 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 allindice

Bocchi Cinzia 03/01/2015

1) Per ogni citt trovare il numero di hotel


SELECT
FROM
GROUP BY

H.citta, COUNT(*) AS NumeroHotel


hotel H
H.citta

passo 1 Sulla tabella hotel viene effettuato un raggruppamento in base al campo citta.
codHotel
100
110
140
120

nome
Miramare
Marittimo
Fiesta
La baita

citta
Rimini
Rimini
Rimini
Aosta

gruppo 1 citt Rimini

130

Miramare

Napoli

gruppo 3 citt Napoli

150

Fiesta

Torino

gruppo 2 citt Aosta

gruppo 4 citt Torino

passo 2 Viene eseguita la funzione count presente in select per ogni gruppo.
codHotel
100
110
140

nome
Miramare
Marittimo
Fiesta

citta
Rimini
Rimini
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

gruppo 1 citt Rimini count=3

passo 3 Viene effettuata la proiezione sui campi della select.


citta
Rimini
Aosta
Napoli
Torino

NumeroHotel
3
1
1
1
torna allindice
6

Bocchi Cinzia 03/01/2015

2) Per ogni hotel trovare il numero di stanze occupate


SELECT
FROM
WHERE
GROUP BY

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


hotel H, stanza S
H.codHotel = S.codHotel AND S.occupata = 1
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
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
110
110
110
110
110
110
110
110
110
110
110
110

nome
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo

citta
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini

numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130

tipo
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
7

Bocchi Cinzia 03/01/2015

110
110
110
110
110
110
110
110
110
110
110
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
130
130
130
130
130
130
130
130
130
130
130
130
130
130
130

Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare

Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli

22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55

130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140

singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia

300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00

0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
8

Bocchi Cinzia 03/01/2015

130
130
130
130
130
130
130
130
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150

Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino

58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2

140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150

singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola

100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00

1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
9

Bocchi Cinzia 03/01/2015

150
150
150
150
150

Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

Torino
Torino
Torino
Torino
Torino

3
4
5
6
7

150
150
150
150
150

singola
doppia
singola
doppia
singola

150,00
250,00
160,00
350,00
100,00

0
1
1
1
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
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

nome
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
Miramare
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

citta
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Aosta
Aosta
Aosta
Aosta
Napoli
Napoli
Napoli
Rimini
Rimini
Torino
Torino
Torino
Torino
Torino
Torino
Torino

numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

tipo
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1

passo 3 Viene applicata lulteriore 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
100
100
100
110
120
120

nome
Miramare
Miramare
Miramare
Marittimo
La baita
La baita

citta
Rimini
Rimini
Rimini
Rimini
Aosta
Aosta

numStanza
1
2
4
1
1
4

codHotel
100
100
100
110
120
120

tipo
singola
doppia
doppia
singola
singola
singola

prezzo
60,00
58,00
61,00
60,00
100,00
200,00

occupata
1
1
1
1
1
1
10

Bocchi Cinzia 03/01/2015

140
140
150
150
150
150

Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

Rimini
Rimini
Torino
Torino
Torino
Torino

55
58
4
5
6
7

140
140
150
150
150
150

doppia
singola
doppia
singola
doppia
singola

99,00
100,00
250,00
160,00
350,00
100,00

1
1
1
1
1
1

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

nome
Miramare
Miramare
Miramare

...
...
...
...

...
...
...
...

gruppo 1: 100 Miramare

110

Marittimo

...

...

gruppo 2: 110 Marittimo

120
120
140
140
150
150
150
150

La baita
La baita
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...

gruppo 3: 120 La baita


gruppo 4: 140 Fiesta

gruppo 5: 150 Fiesta

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


codHotel
100
100
100

nome
Miramare
Miramare
Miramare

...
...
...
...

...
...
...
...

110

Marittimo

...

...

120
120
140
140
150
150
150
150

La baita
La baita
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...

gruppo 1: 100 Miramare count=3

gruppo 2: 110 Marittimo count=1

gruppo 3: 120 La baita count=2


gruppo 4: 140 Fiesta count=2

gruppo 5: 150 Fiesta count=4

11

Bocchi Cinzia 03/01/2015

passo 6 Viene effettuata la proiezione sui campi della select.


codHotel
100
110
120
140
150

nome
Miramare
Marittimo
La baita
Fiesta
Fiesta

NumStanzeOccupate
3
1
2
2
4

Come si pu notare, il codice dellhotel consente di distinguere tra hotel che hanno lo
stesso nome.
torna allindice

Prima alternativa corretta


SELECT
FROM
WHERE
GROUP BY

H.nome, COUNT(*) AS NumStanzeOccupate


hotel H, stanza S
H.codHotel = S.codHotel AND S.occupata = 1
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
Miramare
Marittimo
La baita
Fiesta
Fiesta

NumStanzeOccupate
3
1
2
2
4

torna allindice

12

Bocchi Cinzia 03/01/2015

Seconda alternativa corretta


SELECT
FROM
WHERE
GROUP BY

S.codHotel, COUNT(*) AS NumStanzeOccupate


stanza S
S.occupata = 1
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
1
2
4
1
1
4
55
58
4
5
6
7

codHotel
100
100
100
110
120
120
140
140
150
150
150
150

tipo
singola
doppia
doppia
singola
singola
singola
doppia
singola
doppia
singola
doppia
singola

prezzo
60,00
58,00
61,00
60,00
100,00
200,00
99,00
100,00
250,00
160,00
350,00
100,00

occupata
1
1
1
1
1
1
1
1
1
1
1
1

passo 2 Viene eseguito il raggruppamento sul campo codHotel.


numStanza
1
2
4

codHotel
100
100
100

tipo
singola
doppia
doppia

prezzo
60,00
58,00
61,00

occupata
1
1
1

gruppo 1 100

110

singola

60,00

gruppo 2 110

1
4
55
58
4
5
6
7

120
120
140
140
150
150
150
150

singola
singola
doppia
singola
doppia
singola
doppia
singola

100,00
200,00
99,00
100,00
250,00
160,00
350,00
100,00

1
1
1
1
1
1
1
1

gruppo 3 120
gruppo 4 140

gruppo 5 150

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

13

Bocchi Cinzia 03/01/2015

numStanza
1
2
4

codHotel
100
100
100

tipo
singola
doppia
doppia

prezzo
60,00
58,00
61,00

occupata
1
1
1

gruppo 1 100 count=3

110

singola

60,00

gruppo 2 110 count=1

1
4
55
58
4
5
6
7

120
120
140
140
150
150
150
150

singola
singola
doppia
singola
doppia
singola
doppia
singola

100,00
200,00
99,00
100,00
250,00
160,00
350,00
100,00

1
1
1
1
1
1
1
1

gruppo 3 120 count=2


gruppo 4 140 count=2

gruppo 5 150 count=3

passo 4 Viene effettuata la proiezione sui campi della select.


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

torna allindice

14

Bocchi Cinzia 03/01/2015

Terza alternativa corretta


SELECT
FROM
WHERE
GROUP BY

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


hotel H, stanza S
H.codHotel = S.codHotel
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
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

nome
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
Miramare
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1

gruppo 1: 100 Miramare

gruppo 2: 110 Marittimo

gruppo 3: 120 La baita

gruppo 4: 130 Miramare

gruppo 5: 140 Fiesta

gruppo 6: 150 Fiesta

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

15

Bocchi Cinzia 03/01/2015

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

nome
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
Miramare
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1

gruppo 1: 100 Miramare sum=3

gruppo 2: 110 Marittimo sum=1

gruppo 3: 120 La baita sum=2

gruppo 4: 130 Miramare sum=0

gruppo 5: 140 Fiesta sum=2

gruppo 6: 150 Fiesta sum=4

passo 5 Viene effettuata la proiezione sui campi della select.


codHotel
100
110
120
130
140
150

nome
Miramare
Marittimo
La baita
Miramare
Fiesta
Fiesta

NumStanzeOccupate
3
1
2
0
2
4

In questo caso il resultset ci fornisce uninformazione in pi: lhotel Miramare di codice 130
ha 0 stanze occupate.

torna allindice

16

Bocchi Cinzia 03/01/2015

Quarta alternativa corretta


SELECT
FROM
GROUP BY

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


stanza S
H.codHotel

Se non interessa il nome dellHotel, la terza alternativa pu essere ricondotta a questo


caso.
passo 1 Viene effettuato il raggruppamento sul campo codHotel della tabella stanza
numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1

gruppo 1: 100

gruppo 2: 110

gruppo 3: 120

gruppo 4: 130

gruppo 5: 140

gruppo 6: 150

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

17

Bocchi Cinzia 03/01/2015

numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1

gruppo 1: 100 sum=3

gruppo 2: 110 sum=1

gruppo 3: 120 sum=2

gruppo 4: 130 sum=0

gruppo 5: 140 sum=2

gruppo 6: 150 sum=4

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 uninformazione in pi: lhotel di codice 130 ha 0
stanze occupate.

torna allindice

18

Bocchi Cinzia 03/01/2015

Quinta alternativa corretta


SELECT
FROM
WHERE
GROUP BY

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


hotel H, stanza S
H.codHotel = S.codHotel
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
Miramare
Marittimo
La baita
Miramare
Fiesta
Fiesta

NumStanzeOccupate
3
1
2
0
2
4

torna allindice

Alternativa corretta solo in mancanza di hotel omonimi


SELECT
FROM
WHERE
GROUP BY

H.nome, COUNT(*) AS NumStanzeOccupate


hotel H, stanza S
H.codHotel = S.codHotel AND S.occupata = 1
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
100
100
100

nome
Miramare
Miramare
Miramare

...
...
...
...

...
...
...
...

110

Marittimo

...

...

120
120
140
140
150
150
150
150

La baita
La baita
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...

gruppo 1: Miramare

gruppo 2: Marittimo

gruppo 3: La baita

gruppo 4: Fiesta

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


codHotel
100
100
100

nome
Miramare
Miramare
Miramare

...
...
...
...

...
...
...
...

110

Marittimo

...

...

120
120
140
140
150
150
150
150

La baita
La baita
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...

gruppo 1: Miramare count=3

gruppo 2: Marittimo count=1

gruppo 3: La baita count=2

gruppo 4: Fiesta count=6

passo 6 Viene effettuata la proiezione sui campi della select.


nome
Miramare
Marittimo
La baita
Fiesta

NumStanzeOccupate
3
1
2
6

torna allindice

20

Bocchi Cinzia 03/01/2015

Alternativa corretta, analoga allalternativa 2, ma non ottimizzata


SELECT
FROM
WHERE
GROUP BY

H.codHotel, COUNT(*) AS NumStanzeOccupate


hotel H, stanza S
H.codHotel = S.codHotel AND S.occupata = 1
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 lequi-join. Se non serve il nome dellhotel,
sufficiente utilizzare la tabella stanza. Si veda la seconda alternativa corretta.

torna allindice

Alternativa corretta, analoga allalternativa 4, ma non ottimizzata


SELECT
FROM
WHERE
GROUP BY

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


hotel H, stanza S
H.codHotel = S.codHotel
H.codHotel

Il resultset fornisce le informazioni richieste, tuttavia viene effettuato del lavoro superfluo
per il prodotto cartesiano delle tabelle e lequi-join. Se non serve il nome dellhotel,
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 allindice
21

Bocchi Cinzia 03/01/2015

Alternativa errata
SELECT
FROM
WHERE
GROUP BY

H.nome
hotel H, stanza S
H.codHotel = S.codHotel AND S.occupata = 1
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
100
100
100

nome
Miramare
Miramare
Miramare

...
...
...
...

...
...
...
...

110

Marittimo

...

...

120
120
140
140
150
150
150
150

La baita
La baita
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...

gruppo 1: Miramare

gruppo 2: Marittimo
gruppo 3: La baita

gruppo 4: 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 allindice

22

Bocchi Cinzia 03/01/2015

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


indipendentemente dalla tipologia
SELECT
FROM
WHERE
GROUP BY

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


PrezzoMassimo
hotel H, stanza S
H.codHotel = S.codHotel
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
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
110
110
110
110
110
110
110
110
110

nome
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo

citta
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini

numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120

tipo
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
23

Bocchi Cinzia 03/01/2015

110
110
110
110
110
110
110
110
110
110
110
110
110
110
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
130
130
130
130
130
130
130
130
130
130
130
130

Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare

Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli

3
4
21
22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21

120
120
130
130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130

singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia

150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00

0
1
0
0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
24

Bocchi Cinzia 03/01/2015

130
130
130
130
130
130
130
130
130
130
130
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150

Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino

22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55

130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140

singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia

300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00

0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
25

Bocchi Cinzia 03/01/2015

150
150
150
150
150
150
150
150

Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino

58
1
2
3
4
5
6
7

140
150
150
150
150
150
150
150

singola
doppia
singola
singola
doppia
singola
doppia
singola

100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00

1
0
0
0
1
1
1
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
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

nome
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
Miramare
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

citta
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Aosta
Aosta
Aosta
Aosta
Napoli
Napoli
Napoli
Rimini
Rimini
Torino
Torino
Torino
Torino
Torino
Torino
Torino

numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

tipo
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
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
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

nome
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
Miramare
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

gruppo 1: 100 Miramare

gruppo 2: 110 Marittimo

gruppo 3: 120 La baita

gruppo 4: 130 Miramare

gruppo 5: 140 Fiesta

gruppo 6: 150 Fiesta

passo 4 Vengono eseguite le funzioni MIN e MAX presenti nella select, per ciascun
gruppo.
codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150

nome
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
Miramare
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

gruppo 1: 100 Miramare min=58 max=65

gruppo 2: 110 Marittimo min=60 max=95

gruppo 3: 120 La baita min=95 max=200

gruppo 4: 130 Miramare min=150 max=300

gruppo 5: 140 Fiesta min=99 max=100

27

Bocchi Cinzia 03/01/2015

150
150
150
150
150

Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...

...
...
...
...
...

150,00
250,00
160,00
350,00
100,00

...
...
...
...
...

gruppo 6: 150 Fiesta min=100 max=350

passo 5 Viene effettuata la proiezione sui campi della select.


codHotel
100
110
120
130
140
150

nome
Miramare
Marittimo
La baita
Miramare
Fiesta
Fiesta

PrezzoMinimo PrezzoMassimo
58
65
60
95
95
200
150
300
99
100
100
350
torna allindice

Prima alternativa corretta


SELECT
FROM
WHERE
GROUP BY

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


PrezzoMassimo
hotel H, stanza S
H.codHotel = S.codHotel
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
Miramare
Marittimo
La baita
Miramare
Fiesta
Fiesta

PrezzoMinimo PrezzoMassimo
58
65
60
95
95
200
150
300
99
100
100
350

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

Bocchi Cinzia 03/01/2015

Seconda alternativa corretta


SELECT
FROM
GROUP BY

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


PrezzoMassimo
stanza S
S.codHotel

Lalternativa utile nel caso non interessi il nome dellhotel.


passo 1 Viene effettuato il raggruppamento sul campo codHotel della tabella stanza
numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

gruppo 1: 100

gruppo 2: 110

gruppo 3: 120

gruppo 4: 130
gruppo 5: 140

gruppo 6: 150

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

29

Bocchi Cinzia 03/01/2015

numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

gruppo 1: 100 min=58 max=65

gruppo 2: 110 min=60 max=95

gruppo 3: 120 min=95 max=200

gruppo 4: 130 min=150 max=300


gruppo 5: 140 min=99 max=100

gruppo 6: 150 150 min=100 max=350

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 allindice

30

Bocchi Cinzia 03/01/2015

Alternativa corretta solo in mancanza di hotel omonimi


SELECT
FROM
WHERE
GROUP BY

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


PrezzoMassimo
hotel H, stanza S
H.codHotel = S.codHotel
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
100
100
100
100
130
130
130
110
110
110
120
120
120
120
140
140
150
150
150
150
150
150
150

nome
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

prezzo
60,00
58,00
65,00
61,00
250,00
300,00
150,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

gruppo 1: Miramare

gruppo 2: Marittimo

gruppo 3: La baita

gruppo 4: Fiesta

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

31

Bocchi Cinzia 03/01/2015

codHotel
100
100
100
100
130
130
130
110
110
110
120
120
120
120
140
140
150
150
150
150
150
150
150

nome
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

prezzo
60,00
58,00
65,00
61,00
250,00
300,00
150,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

gruppo 1: Miramare min=58 max= 300

gruppo 2: Marittimo min=60 max=95

gruppo 3: La baita min=95 max=200

gruppo 4: Fiesta min=99 max=350

passo 5 Viene effettuata la proiezione sui campi della select.


nome
Miramare
Marittimo
La baita
Fiesta

PrezzoMinimo PrezzoMassimo
58
300
60
95
95
200
99
350

torna allindice

32

Bocchi Cinzia 03/01/2015

Alternativa corretta, analoga allalternativa 2, ma non ottimizzata


SELECT
FROM
WHERE
GROUP BY

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


PrezzoMassimo
hotel H, stanza S
H.codHotel = S.codHotel
H.codHotel

Il resultset fornisce le informazioni richieste, tuttavia viene effettuato del lavoro superfluo
per il prodotto cartesiano delle tabelle e lequi-join. Se non serve il nome dellhotel,
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 allindice

Alternativa incompleta
SELECT
FROM
WHERE
GROUP BY

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


hotel H, stanza S
H.codHotel = S.codHotel
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
100
110
120
130
140
150

nome
Miramare
Marittimo
La baita
Miramare
Fiesta
Fiesta

PrezzoMassimo
65
95
200
300
100
350
torna allindice
33

Bocchi Cinzia 03/01/2015

Alternativa errata
SELECT
FROM
WHERE
GROUP BY

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


PrezzoMassimo
stanza S
S.tipo = qualsiasi
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 allindice

34

Bocchi Cinzia 03/01/2015

4) Per ogni hotel trovare il prezzo minimo e massimo delle stanze singole
SELECT
FROM
WHERE
GROUP BY

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


PrezzoMassimo
hotel H, stanza S
H.codHotel = S.codHotel AND S.tipo = singola
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
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
110
110
110
110
110
110
110
110
110
110
110

nome
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo

citta
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini

numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120

tipo
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
35

Bocchi Cinzia 03/01/2015

110
110
110
110
110
110
110
110
110
110
110
110
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
130
130
130
130
130
130
130
130
130
130
130
130
130
130

Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare

Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli

21
22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21
22
25

130
130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130
130
130

doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola

250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00

0
0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
0
0
36

Bocchi Cinzia 03/01/2015

130
130
130
130
130
130
130
130
130
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
140
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150

Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino

55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1

140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150

doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia

99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00

1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
37

Bocchi Cinzia 03/01/2015

150
150
150
150
150
150

Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

Torino
Torino
Torino
Torino
Torino
Torino

2
3
4
5
6
7

150
150
150
150
150
150

singola
singola
doppia
singola
doppia
singola

180,00
150,00
250,00
160,00
350,00
100,00

0
0
1
1
1
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
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

nome
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
Miramare
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

citta
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Aosta
Aosta
Aosta
Aosta
Napoli
Napoli
Napoli
Rimini
Rimini
Torino
Torino
Torino
Torino
Torino
Torino
Torino

numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

tipo
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
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
100
100
110
110
120
120
120
130
130
140
150
150
150
150

nome
Miramare
Miramare
Marittimo
Marittimo
La baita
La baita
La baita
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

citta
Rimini
Rimini
Rimini
Rimini
Aosta
Aosta
Aosta
Napoli
Napoli
Rimini
Torino
Torino
Torino
Torino

numStanza
1
3
1
3
1
3
4
22
25
58
2
3
5
7

codHotel
100
100
110
110
120
120
120
130
130
140
150
150
150
150

tipo
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola

prezzo
60,00
65,00
60,00
95,00
100,00
150,00
200,00
300,00
150,00
100,00
180,00
150,00
160,00
100,00

occupata
1
0
1
0
1
0
1
0
0
1
0
0
1
1

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

nome
Miramare
Miramare
Marittimo
Marittimo
La baita
La baita
La baita
Miramare
Miramare

...
...
...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...
...
...

prezzo
60,00
65,00
60,00
95,00
100,00
150,00
200,00
300,00
150,00

...
...
...
...
...
...
...
...
...
...

140

Fiesta

...

...

100,00

...

gruppo 5: 140 Fiesta

150
150
150
150

Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...

...
...
...
...

180,00
150,00
160,00
100,00

...
...
...
...

gruppo 6: 150 Fiesta

gruppo 1: 100 Miramare


gruppo 2: 110 Marittimo

gruppo 3: 120 La baita

gruppo 4: 130 Miramare

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

39

Bocchi Cinzia 03/01/2015

codHotel
100
100
110
110
120
120
120
130
130

nome
Miramare
Miramare
Marittimo
Marittimo
La baita
La baita
La baita
Miramare
Miramare

...
...
...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...
...
...

prezzo
60,00
65,00
60,00
95,00
100,00
150,00
200,00
300,00
150,00

...
...
...
...
...
...
...
...
...
...

140

Fiesta

...

...

100,00

...

gruppo 5: 140 Fiesta min=100 max=100

150
150
150
150

Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...

...
...
...
...

180,00
150,00
160,00
100,00

...
...
...
...

gruppo 6: 150 Fiesta min=100 max=180

gruppo 1: 100 Miramare min=60 max=65


gruppo 2: 110 Marittimo min=60 max=95

gruppo 3: 120 La baita min=100 max=200

gruppo 4: 130 Miramare min=150 max=300

passo 6 Viene effettuata la proiezione sui campi della select.


codHotel
100
110
120
130
140
150

nome
Miramare
Marittimo
La baita
Miramare
Fiesta
Fiesta

PrezzoMinimo PrezzoMassimo
60
65
60
95
100
200
150
300
100
100
100
180

torna allindice

40

Bocchi Cinzia 03/01/2015

Prima alternativa corretta


SELECT
FROM
WHERE
GROUP BY

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


PrezzoMassimo
hotel H, stanza S
H.codHotel = S.codHotel AND S.tipo = singola
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
Miramare
Marittimo
La baita
Miramare
Fiesta
Fiesta

PrezzoMinimo PrezzoMassimo
60
65
60
95
100
200
150
300
100
100
100
180

torna allindice

Seconda alternativa corretta


SELECT
FROM
WHERE
GROUP BY

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


PrezzoMassimo
stanza S
S.tipo = singola
S.codHotel

Lalternativa utile nel caso non interessi il nome dellhotel.


passo 1 Viene applicata la condizione where S.tipo = singola: le righe relative a
stanze con tipologia diversa vengono eliminate
numStanza
1
3
1
3
1
3
4

codHotel
100
100
110
110
120
120
120

tipo
singola
singola
singola
singola
singola
singola
singola

prezzo
60,00
65,00
60,00
95,00
100,00
150,00
200,00

occupata
1
0
1
0
1
0
1
41

Bocchi Cinzia 03/01/2015

22
25
58
2
3
5
7

130
130
140
150
150
150
150

singola
singola
singola
singola
singola
singola
singola

300,00
150,00
100,00
180,00
150,00
160,00
100,00

0
0
1
0
0
1
1

passo 2 Viene effettuato il raggruppamento sul campo codHotel della tabella stanza
numStanza
1
3
1
3
1
3
4
22
25

codHotel
100
100
110
110
120
120
120
130
130

...
...
...
...
...
...
...
...
...
...

prezzo
60,00
65,00
60,00
95,00
100,00
150,00
200,00
300,00
150,00

...
...

58

140

...

100,00

...

gruppo 5: 140

2
3
5
7

150
150
150
150

...
...
...
...

180,00
150,00
160,00
100,00

...
...
...
...

gruppo 6: 150

...
...
...
...
...
...
...

gruppo 1: 100
gruppo 2: 110
gruppo 3: 120

gruppo 4: 130

passo 3 Vengono eseguite le funzioni MIN e MAX presenti nella select, per ciascun
gruppo.
numStanza
1
3
1
3
1
3
4
22
25

codHotel
100
100
110
110
120
120
120
130
130

...
...
...
...
...
...
...
...
...
...

prezzo
60,00
65,00
60,00
95,00
100,00
150,00
200,00
300,00
150,00

...
...

58

140

...

100,00

...

gruppo 5: 140 min=100 max=100

2
3
5
7

150
150
150
150

...
...
...
...

180,00
150,00
160,00
100,00

...
...
...
...

gruppo 6: 150 min= 100 max=180

...
...
...
...
...
...
...

gruppo 1: 100 min=60 max=65


gruppo 2: 110 min=60 max=95
gruppo 3: 120 min=100 max=200

gruppo 4: 130 min=150 max=300

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 allindice

Alternativa corretta solo in mancanza di hotel omonimi


SELECT
FROM
WHERE
GROUP BY

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


PrezzoMassimo
hotel H, stanza S
H.codHotel = S.codHotel AND S.tipo = singola
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
100
100
130
130
110
110
120
120
120
140
150
150
150
150

nome
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
La baita
La baita
La baita
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

prezzo
60,00
65,00
300,00
150,00
60,00
95,00
100,00
150,00
200,00
100,00
180,00
150,00
160,00
100,00

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

gruppo 1: Miramare

gruppo 2: Marittimo

gruppo 3: La baita

gruppo 4: Fiesta

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

Bocchi Cinzia 03/01/2015

codHotel
100
100
130
130
110
110
120
120
120
140
150
150
150
150

nome
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
La baita
La baita
La baita
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

prezzo
60,00
65,00
300,00
150,00
60,00
95,00
100,00
150,00
200,00
100,00
180,00
150,00
160,00
100,00

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

gruppo 1: Miramare min=60 max=300

gruppo 2: Marittimo min=60 max=95

gruppo 3: La baita min=100 max=200

gruppo 4: Fiesta min=100 max=180

passo 6 Viene effettuata la proiezione sui campi della select.


nome
Miramare
Marittimo
La baita
Fiesta

PrezzoMinimo PrezzoMassimo
60
300
60
95
100
200
100
180

torna allindice

Alternativa corretta, analoga allalternativa 2, ma non ottimizzata


SELECT
FROM
WHERE
GROUP BY

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


PrezzoMassimo
hotel H, stanza S
H.codHotel = S.codHotel AND S.tipo = singola
H.codHotel

Il resultset fornisce le informazioni richieste, tuttavia viene effettuato del lavoro superfluo
per il prodotto cartesiano delle tabelle e lequi-join. Se non serve il nome dellhotel,
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 allindice

Prima alternativa errata


SELECT
FROM
GROUP BY

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


AS PrezzoMassimo
stanza S, hotel H
H.codHotel, H.nome

Mancano lequi 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 allindice

Seconda alternativa errata


SELECT
FROM
GROUP BY
HAVING

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


PrezzoMassimo
stanza S
S.codHotel
S.tipo = singola

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

45

Bocchi Cinzia 03/01/2015

numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2
3
4
5
6
7

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

tipo
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
doppia
singola
doppia
singola

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00
150,00
250,00
160,00
350,00
100,00

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0
0
1
1
1
1

gruppo 1: 100

gruppo 2: 110

gruppo 3: 120

gruppo 4: 130

gruppo 5: 140

gruppo 6: 150

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


gruppo.
numStanza
1
2
3
4
1
2
3
1
2
3
4
21
22
25
55
58
1
2

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150

tipo
singola
doppia
singola
doppia
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola

prezzo
60,00
58,00
65,00
61,00
60,00
80,00
95,00
100,00
95,00
150,00
200,00
250,00
300,00
150,00
99,00
100,00
250,00
180,00

occupata
1
1
0
1
1
0
0
1
0
0
1
0
0
0
1
1
0
0

gruppo 1: 100 min=58 max=65

gruppo 2: 110 min=60 max=95

gruppo 3: 120 min=95 max=200

gruppo 4: 130 min=150 max=300

gruppo 5: 140 min=99 max=100

46

Bocchi Cinzia 03/01/2015

3
4
5
6
7

150
150
150
150
150

singola
doppia
singola
doppia
singola

150,00
250,00
160,00
350,00
100,00

0
1
1
1
1

gruppo 6: 150 min=100 max=350

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 lintero
gruppo, come sono per esempio min e max. Di conseguenza non possibile verificarla e
viene restituito un errore.

torna allindice

47

Bocchi Cinzia 03/01/2015

5) Per ogni cliente ( sufficiente lidCliente), trovare il numero di prenotazioni


effettuate in hotel di Rimini nellanno 2013 (si consideri solo dataInizio)
SELECT
FROM
WHERE
GROUP BY

P.idCliente, COUNT(*) AS NumeroPrenotazioni


prenotazione P, hotel H
P.codHotel = H.codHotel AND H.citta = Rimini AND P.datainizio
BETWEEN 2013-01-01 AND 2013-12-31
P.idCliente

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


codHot
el
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
100
110
110
110
110
110
110
110
110
110
110
110
110
110
110
110

nome

citta

numSt
anza

codHot
el

idClient
e

data Inizio

dataFine

Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo
Marittimo

Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini

1
1
2
55
3
55
58
4
22
4
5
1
1
2
3
1
3
3
1
1
2
55
3
55
58
4
22
4
5
1
1
2
3

100
100
110
140
100
140
140
120
130
150
150
120
150
150
150
100
100
110
100
100
110
140
100
140
140
120
130
150
150
120
150
150
150

2
4
1
3
4
5
6
7
1
3
4
2
3
5
6
7
4
2
2
4
1
3
4
5
6
7
1
3
4
2
3
5
6

2013-07-14
2013-08-10
2013-07-02
2013-08-20
2013-09-01
2013-09-12
2013-07-01
2014-05-10
2014-06-05
2015-03-01
2015-03-15
2015-05-20
2015-07-12
2015-07-20
2015-07-15
2015-07-13
2015-07-19
2015-07-11
2013-07-14
2013-08-10
2013-07-02
2013-08-20
2013-09-01
2013-09-12
2013-07-01
2014-05-10
2014-06-05
2015-03-01
2015-03-15
2015-05-20
2015-07-12
2015-07-20
2015-07-15

2013-07-20
2013-08-20
2013-07-09
2013-08-28
2013-09-18
2013-09-30
2013-07-15
2014-05-20
2014-06-15

2013-07-20
2013-08-20
2013-07-09
2013-08-28
2013-09-18
2013-09-30
2013-07-15
2014-05-20
2014-06-15

48

Bocchi Cinzia 03/01/2015

110
110
110
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
120
130
130
130
130
130
130
130
130
130
130
130
130
130
130
130
130
130
130
140
140
140
140
140
140
140
140
140
140

Marittimo
Marittimo
Marittimo
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
La baita
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

Rimini
Rimini
Rimini
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Aosta
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Napoli
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini

1
3
3
1
1
2
55
3
55
58
4
22
4
5
1
1
2
3
1
3
3
1
1
2
55
3
55
58
4
22
4
5
1
1
2
3
1
3
3
1
1
2
55
3
55
58
4
22
4

100
100
110
100
100
110
140
100
140
140
120
130
150
150
120
150
150
150
100
100
110
100
100
110
140
100
140
140
120
130
150
150
120
150
150
150
100
100
110
100
100
110
140
100
140
140
120
130
150

7
4
2
2
4
1
3
4
5
6
7
1
3
4
2
3
5
6
7
4
2
2
4
1
3
4
5
6
7
1
3
4
2
3
5
6
7
4
2
2
4
1
3
4
5
6
7
1
3

2015-07-13
2015-07-19
2015-07-11
2013-07-14
2013-08-10
2013-07-02
2013-08-20
2013-09-01
2013-09-12
2013-07-01
2014-05-10
2014-06-05
2015-03-01
2015-03-15
2015-05-20
2015-07-12
2015-07-20
2015-07-15
2015-07-13
2015-07-19
2015-07-11
2013-07-14
2013-08-10
2013-07-02
2013-08-20
2013-09-01
2013-09-12
2013-07-01
2014-05-10
2014-06-05
2015-03-01
2015-03-15
2015-05-20
2015-07-12
2015-07-20
2015-07-15
2015-07-13
2015-07-19
2015-07-11
2013-07-14
2013-08-10
2013-07-02
2013-08-20
2013-09-01
2013-09-12
2013-07-01
2014-05-10
2014-06-05
2015-03-01

2013-07-20
2013-08-20
2013-07-09
2013-08-28
2013-09-18
2013-09-30
2013-07-15
2014-05-20
2014-06-15

2013-07-20
2013-08-20
2013-07-09
2013-08-28
2013-09-18
2013-09-30
2013-07-15
2014-05-20
2014-06-15

2013-07-20
2013-08-20
2013-07-09
2013-08-28
2013-09-18
2013-09-30
2013-07-15
2014-05-20
2014-06-15
49

Bocchi Cinzia 03/01/2015

140
140
140
140
140
140
140
140
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150
150

Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino
Torino

5
1
1
2
3
1
3
3
1
1
2
55
3
55
58
4
22
4
5
1
1
2
3
1
3
3

150
120
150
150
150
100
100
110
100
100
110
140
100
140
140
120
130
150
150
120
150
150
150
100
100
110

4
2
3
5
6
7
4
2
2
4
1
3
4
5
6
7
1
3
4
2
3
5
6
7
4
2

2015-03-15
2015-05-20
2015-07-12
2015-07-20
2015-07-15
2015-07-13
2015-07-19
2015-07-11
2013-07-14
2013-08-10
2013-07-02
2013-08-20
2013-09-01
2013-09-12
2013-07-01
2014-05-10
2014-06-05
2015-03-01
2015-03-15
2015-05-20
2015-07-12
2015-07-20
2015-07-15
2015-07-13
2015-07-19
2015-07-11

2013-07-20
2013-08-20
2013-07-09
2013-08-28
2013-09-18
2013-09-30
2013-07-15
2014-05-20
2014-06-15

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


con record non correlati vengono eliminate.
codHot
el
100
100
100
100
100
110
110
120
120
120
130
140
140
140
150
150

nome

citta

numSt
anza

codHot
el

idClient
e

data Inizio

dataFine

Miramare
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
La baita
La baita
La baita
Miramare
Fiesta
Fiesta
Fiesta
Fiesta
Fiesta

Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Aosta
Aosta
Aosta
Napoli
Rimini
Rimini
Rimini
Torino
Torino

1
1
3
1
3
2
3
4
1
3
22
55
55
58
4
5

100
100
100
100
100
110
110
120
120
110
130
140
140
140
150
150

2
4
4
7
4
1
2
7
2
2
1
3
5
6
3
4

2013-07-14
2013-08-10
2013-09-01
2015-07-13
2015-07-19
2013-07-02
2015-07-11
2014-05-10
2015-05-20
2015-07-11
2014-06-05
2013-08-20
2013-09-12
2013-07-01
2015-03-01
2015-03-15

2013-07-20
2013-08-20
2013-09-18

2013-07-09
2014-05-20

2014-06-15
2013-08-28
2013-09-30
2013-07-15

50

Bocchi Cinzia 03/01/2015

150
150
150

Fiesta
Fiesta
Fiesta

Torino
Torino
Torino

1
2
3

150
150
150

3
5
6

2015-07-12
2015-07-20
2015-07-15

passo 3 Viene applicata la condizione where H.citta = Rimini: tutte gli hotel che non
sono di Rimini vengono eliminati.
codHot
el
100
100
100
100
100
110
110
140
140
140

nome

citta

numSt
anza

codHot
el

idClient
e

data Inizio

dataFine

Miramare
Miramare
Miramare
Miramare
Miramare
Marittimo
Marittimo
Fiesta
Fiesta
Fiesta

Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini

1
1
3
1
3
2
3
55
55
58

100
100
100
100
100
110
110
140
140
140

2
4
4
7
4
1
2
3
5
6

2013-07-14
2013-08-10
2013-09-01
2015-07-13
2015-07-19
2013-07-02
2015-07-11
2013-08-20
2013-09-12
2013-07-01

2013-07-20
2013-08-20
2013-09-18

2013-07-09
2013-08-28
2013-09-30
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
el
100
100
110
140
140
140

nome

citta

numSt
anza

codHot
el

idClient
e

data Inizio

dataFine

Miramare
Miramare
Marittimo
Fiesta
Fiesta
Fiesta

Rimini
Rimini
Rimini
Rimini
Rimini
Rimini

1
3
2
55
55
58

100
100
110
140
140
140

4
4
1
3
5
6

2013-08-10
2013-09-01
2013-07-02
2013-08-20
2013-09-12
2013-07-01

2013-08-20
2013-09-18
2013-07-09
2013-08-28
2013-09-30
2013-07-15

passo 5 Viene eseguito il raggruppamento sul campo idCliente della tabella


prenotazione.

51

Bocchi Cinzia 03/01/2015

codHotel
100
100

...
...
...

...
...
...

idCliente
4
4

...
...
...

gruppo 1 idCliente 4

110

...

...

...

gruppo 2 idCliente 1

140

...

...

...

gruppo 3 idCliente 3

140

...

...

...

gruppo 4 idCliente 5

140

...

...

...

gruppo 5 idCliente 6

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


codHotel
100
100

...
...
...

...
...
...

idCliente
4
4

...
...
...

110

...

...

...

gruppo 2 idCliente 1 count=1

140

...

...

...

gruppo 3 idCliente 3 count=1

140

...

...

...

gruppo 4 idCliente 5 count=1

140

...

...

...

gruppo 5 idCliente 6 count=1

gruppo 1 idCliente 4 count=2

passo 7 Vengono proiettati i campi presenti in select.


idCliente
4
1
3
5
6

NumeroPrenotazioni
2
1
1
1
1

torna allindice
52

Bocchi Cinzia 03/01/2015

Alternativa analoga alla soluzione principale ma non ottimizzata


SELECT
FROM
WHERE
GROUP BY

P.idCliente, COUNT(*) AS NumeroPrenotazioni


prenotazione P, hotel H, stanza S
P.codHotel = S.codHotel AND S.codHotel = H.codHotel AND H.citta =
Rimini AND P.datainizio BETWEEN 2013-01-01 AND 2013-12-31
P.idCliente

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


per ottenere la stessa soluzione.
torna allindice

Alternativa errata
SELECT
FROM
WHERE
GROUP BY

P.idCliente
prenotazione P, hotel H
P.codHotel = H.codHotel AND H.citta = Rimini AND P.datainizio
BETWEEN 2013-01-01 AND 2013-12-31
P.idCliente

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


atteso.
idCliente
4
1
3
5
6

torna allindice

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
FROM
GROUP BY
HAVING

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


stanza S
S.tipo
COUNT(*) > 100

passo 1 Viene effettuato il raggruppamento sul campo tipo della tabella stanza.
numStanza
1
3
1
3
1
3
4
22
25
58
2
3
5
7
2
4
2
2
21
55
1
4
6

codHotel
100
100
110
110
120
120
120
130
130
140
150
150
150
150
100
100
110
120
130
140
150
150
150

tipo
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
doppia
doppia
doppia
doppia
doppia
doppia
doppia
doppia
doppia

prezzo
60,00
65,00
60,00
95,00
100,00
150,00
200,00
300,00
150,00
100,00
180,00
150,00
160,00
100,00
58,00
61,00
80,00
95,00
250,00
99,00
250,00
250,00
350,00

occupata
1
0
1
0
1
0
1
0
0
1
0
0
1
1
1
1
0
0
0
1
0
1
1

gruppo 1 singola

gruppo 2 doppia

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


numStanza
1
3
1
3
1
3
4
22

codHotel
100
100
110
110
120
120
120
130

tipo
singola
singola
singola
singola
singola
singola
singola
singola

prezzo
60,00
65,00
60,00
95,00
100,00
150,00
200,00
300,00

occupata
1
0
1
0
1
0
1
0

gruppo 1 singola avg=133,57

54

Bocchi Cinzia 03/01/2015

25
58
2
3
5
7
2
4
2
2
21
55
1
4
6

130
140
150
150
150
150
100
100
110
120
130
140
150
150
150

singola
singola
singola
singola
singola
singola
doppia
doppia
doppia
doppia
doppia
doppia
doppia
doppia
doppia

150,00
100,00
180,00
150,00
160,00
100,00
58,00
61,00
80,00
95,00
250,00
99,00
250,00
250,00
350,00

0
1
0
0
1
1
1
1
0
0
0
1
0
1
1

gruppo 2 doppia avg=165,89

passo 3 Viene eseguita la funzione COUNT presente in having, per ciascun gruppo.
numStanza
1
3
1
3
1
3
4
22
25
58
2
3
5
7
2
4
2
2
21
55
1
4
6

codHotel
100
100
110
110
120
120
120
130
130
140
150
150
150
150
100
100
110
120
130
140
150
150
150

tipo
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
doppia
doppia
doppia
doppia
doppia
doppia
doppia
doppia
doppia

prezzo
60,00
65,00
60,00
95,00
100,00
150,00
200,00
300,00
150,00
100,00
180,00
150,00
160,00
100,00
58,00
61,00
80,00
95,00
250,00
99,00
250,00
250,00
350,00

occupata
1
0
1
0
1
0
1
0
0
1
0
0
1
1
1
1
0
0
0
1
0
1
1

gruppo 1 singola avg=133,57 count=14

gruppo 2 doppia avg=165,89 count=9

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 lesempio, 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
1
3
1
3
1
3
4
22
25
58
2
3
5
7

codHotel
100
100
110
110
120
120
120
130
130
140
150
150
150
150

tipo
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola

prezzo
60,00
65,00
60,00
95,00
100,00
150,00
200,00
300,00
150,00
100,00
180,00
150,00
160,00
100,00

occupata
1
0
1
0
1
0
1
0
0
1
0
0
1
1

gruppo 1 singola avg=133,57 count=14

passo 5 Vengono proiettati gli attributi in select.


tipo
singola

PrezzoMedio
133,57

torna allindice

Prima alternativa errata


SELECT
FROM
GROUP BY
HAVING

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


stanza S
S.tipo
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 lattributo 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 allindice

56

Bocchi Cinzia 03/01/2015

Seconda alternativa errata


SELECT
FROM
GROUP BY
HAVING

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


PrezzoMedio
stanza S
S.tipo, S.codHotel
NumStanze > 100

passo 1 Viene effettuato il raggruppamento sui campi tipo e codHotel della tabella
stanza.
numStanza
1
3
2
4
1
3
2
1
3
4
2
22
25
21
58
55
2
3
5
7
1
4
6

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

tipo
singola
singola
doppia
doppia
singola
singola
doppia
singola
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
singola
singola
doppia
doppia
doppia

prezzo
60,00
65,00
58,00
61,00
60,00
95,00
80,00
100,00
150,00
200,00
95,00
300,00
150,00
250,00
100,00
99,00
180,00
150,00
160,00
100,00
250,00
250,00
350,00

occupata
1
0
1
1
1
0
0
1
0
1
0
0
0
0
1
1
0
0
1
1
0
1
1

gruppo 1 100 singola


gruppo 2 100 doppia
gruppo 3 110 singola
gruppo 4 110 doppia
gruppo 5 120 singola
gruppo 6 120 doppia
gruppo 7 130 singola
gruppo 8 130 doppia
gruppo 9 140 singola
gruppo 10 140 doppia

gruppo 11 150 singola

gruppo 12 150 doppia

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


numStanza
1
3
2
4
1
3
2
1

codHotel
100
100
100
100
110
110
110
120

tipo
singola
singola
doppia
doppia
singola
singola
doppia
singola

prezzo
60,00
65,00
58,00
61,00
60,00
95,00
80,00
100,00

occupata
1
0
1
1
1
0
0
1

gruppo 1 100 singola count=2


gruppo 2 100 doppia count=2
gruppo 3 110 singola count=2
gruppo 4 110 doppia count=1
gruppo 5 120 singola count=3

57

Bocchi Cinzia 03/01/2015

3
4
2
22
25
21
58
55
2
3
5
7
1
4
6

120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
singola
singola
doppia
doppia
doppia

150,00
200,00
95,00
300,00
150,00
250,00
100,00
99,00
180,00
150,00
160,00
100,00
250,00
250,00
350,00

0
1
0
0
0
0
1
1
0
0
1
1
0
1
1

gruppo 6 120 doppia count=1


gruppo 7 130 singola count=2
gruppo 8 130 doppia count=1
gruppo 9 140 singola count=1
gruppo 10 140 doppia count=1

gruppo 11 150 singola count=4

gruppo 12 150 doppia count=3

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


numStanza
1
3
2
4
1
3
2
1
3
4
2
22
25
21
58
55
2
3
5
7
1
4
6

codHotel
100
100
100
100
110
110
110
120
120
120
120
130
130
130
140
140
150
150
150
150
150
150
150

tipo
singola
singola
doppia
doppia
singola
singola
doppia
singola
singola
singola
doppia
singola
singola
doppia
singola
doppia
singola
singola
singola
singola
doppia
doppia
doppia

prezzo
60,00
65,00
58,00
61,00
60,00
95,00
80,00
100,00
150,00
200,00
95,00
300,00
150,00
250,00
100,00
99,00
180,00
150,00
160,00
100,00
250,00
250,00
350,00

occupata
1
0
1
1
1
0
0
1
0
1
0
0
0
0
1
1
0
0
1
1
0
1
1

gruppo 1 100 singola count=2 avg=62,5


gruppo 2 100 doppia count=2 avg=59,5
gruppo 3 110 singola count=2 avg=77,5
gruppo 4 110 doppia count=1 avg=80
gruppo 5 120 singola count=3 avg=150
gruppo 6 120 doppia count=1 avg=95
gruppo 7 130 singola count=2 avg=225
gruppo 8 130 doppia count=1 avg=250
gruppo 9 140 singola count=1 avg=100
gruppo 10 140 doppia count=1 avg=99

gruppo 11 150 singola count=4 avg=147,5

gruppo 12 150 doppia count=3 avg=283,3

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
1
3
4
2
3
5
7
1
4
6

codHotel
120
120
120
150
150
150
150
150
150
150

tipo
singola
singola
singola
singola
singola
singola
singola
doppia
doppia
doppia

prezzo
100,00
150,00
200,00
180,00
150,00
160,00
100,00
250,00
250,00
350,00

occupata
1
0
1
0
0
1
1
0
1
1

gruppo 5 120 singola count=3 avg=150

gruppo 11 150 singola count=4 avg=147,5

gruppo 12 150 doppia count=3 avg=283,3

passo 5 Vengono proiettati gli attributi in select.


tipo
singola
singola
doppia

codHotel
120
150
150

NumStanze
3
4
3

PrezzoMedio
150
147,5
283,3

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

torna allindice

59

Bocchi Cinzia 03/01/2015

Terza alternativa errata


SELECT
FROM
GROUP BY
HAVING

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


stanza S
S.numStanza
NumStanze > 100

passo 1 Viene eseguito il raggruppamento sul campo numStanza della tabella stanza.
numStanza
1
1
1
1
2
2
2
2
3
3
3
3
4
4
4
5

codHotel
100
110
120
150
100
110
120
150
100
110
120
150
100
120
150
150

tipo
singola
singola
singola
doppia
doppia
doppia
doppia
singola
singola
singola
singola
singola
doppia
singola
doppia
singola

prezzo
60,00
60,00
100,00
250,00
58,00
80,00
95,00
180,00
65,00
95,00
150,00
150,00
61,00
200,00
250,00
160,00

occupata
1
1
1
0
1
0
0
0
0
0
0
0
1
1
1
1

150

doppia

350,00

150

singola

100,00

gruppo 7 numstanza 7

21

130

doppia

250,00

gruppo 8 numstanza 21

22

130

singola

300,00

25

130

singola

150,00

55

140

doppia

99,00

58

140

singola

100,00

gruppo 1 numstanza 1

gruppo 2 numstanza 2

gruppo 3 numstanza 3

gruppo 4 numstanza 4

gruppo 5 numstanza 5
gruppo 6 numstanza 6

gruppo 9 numstanza 22
gruppo 10 numstanza 25
gruppo 11 numstanza 55
gruppo 12 numstanza 58

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

60

Bocchi Cinzia 03/01/2015

numStanza
1
1
1
1
2
2
2
2
3
3
3
3
4
4
4
5

codHotel
100
110
120
150
100
110
120
150
100
110
120
150
100
120
150
150

tipo
singola
singola
singola
doppia
doppia
doppia
doppia
singola
singola
singola
singola
singola
doppia
singola
doppia
singola

prezzo
60,00
60,00
100,00
250,00
58,00
80,00
95,00
180,00
65,00
95,00
150,00
150,00
61,00
200,00
250,00
160,00

occupata
1
1
1
0
1
0
0
0
0
0
0
0
1
1
1
1

150

doppia

350,00

150

singola

100,00

gruppo 7 numstanza 7 count=1

21

130

doppia

250,00

gruppo 8 numstanza 21 count=1

22

130

singola

300,00

25

130

singola

150,00

55

140

doppia

99,00

58

140

singola

100,00

gruppo 1 numstanza 1 count=4

gruppo 2 numstanza 2 count=4

gruppo 3 numstanza 3 count=4

gruppo 4 numstanza 4 count=3

gruppo 5 numstanza 5 count=1


gruppo 6 numstanza 6 count=1

gruppo 9 numstanza 22 count=1


gruppo 10 numstanza 25 count=1
gruppo 11 numstanza 55 count=1
gruppo 12 numstanza 58 count=1

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


numStanza
1
1
1
1
2
2
2
2
3
3
3
3

codHotel
100
110
120
150
100
110
120
150
100
110
120
150

tipo
singola
singola
singola
doppia
doppia
doppia
doppia
singola
singola
singola
singola
singola

prezzo
60,00
60,00
100,00
250,00
58,00
80,00
95,00
180,00
65,00
95,00
150,00
150,00

occupata
1
1
1
0
1
0
0
0
0
0
0
0

gruppo 1 numst 1 count=4 avg=117,5

gruppo 2 numst 2 count=4 avg=103,25

gruppo 3 numst 3 count=4 avg=115

61

Bocchi Cinzia 03/01/2015

4
4
4
5

100
120
150
150

doppia
singola
doppia
singola

61,00
200,00
250,00
160,00

1
1
1
1

150

doppia

350,00

150

singola

100,00

gruppo 7 numst 7 count=1 avg=100

21

130

doppia

250,00

gruppo 8 numst 21 count=1 avg=250

22

130

singola

300,00

25

130

singola

150,00

55

140

doppia

99,00

58

140

singola

100,00

gruppo 4 numst 4 count=3 avg= 170,3

gruppo 5 numst 5 count=1 avg=160


gruppo 6 numst 6 count=1 avg=350

gruppo 9 numst 22 count=1 avg=300


gruppo 10 numst 25 count=1 avg=150
gruppo 11 numst 55 count=1 avg=99
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
1
1
1
1
2
2
2
2
3
3
3
3
4
4
4

codHotel
100
110
120
150
100
110
120
150
100
110
120
150
100
120
150

tipo
singola
singola
singola
doppia
doppia
doppia
doppia
singola
singola
singola
singola
singola
doppia
singola
doppia

prezzo
60,00
60,00
100,00
250,00
58,00
80,00
95,00
180,00
65,00
95,00
150,00
150,00
61,00
200,00
250,00

occupata
1
1
1
0
1
0
0
0
0
0
0
0
1
1
1

gruppo 1 numst 1 count=4 avg=117,5

gruppo 2 numst 2 count=4 avg=103,25

gruppo 3 numst 3 count=4 avg=115

gruppo 4 numst 4 count=3 avg= 170,3

passo 5 Vengono proiettati gli attributi in select.

62

Bocchi Cinzia 03/01/2015

numStanza
1
2
3
4

NumStanze
4
4
4
3

PrezzoMedio
117,5
103,25
115
170,3

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

torna allindice

Quarta alternativa errata


SELECT
FROM
GROUP BY
HAVING

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


stanza S
S.tipo
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 lattributo 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 allindice

Quinta alternativa errata


SELECT
FROM
GROUP BY
HAVING

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


stanza S
S.tipo
COUNT(S.tipo) >= 100

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


numStanza
1
3
1

codHotel
100
100
110

tipo
singola
singola
singola

prezzo
60,00
65,00
60,00

occupata
1
0
1
63

Bocchi Cinzia 03/01/2015

3
1
3
4
22
25
58
2
3
5
7
2
4
2
2
21
55
1
4
6

110
120
120
120
130
130
140
150
150
150
150
100
100
110
120
130
140
150
150
150

singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
singola
doppia
doppia
doppia
doppia
doppia
doppia
doppia
doppia
doppia

95,00
100,00
150,00
200,00
300,00
150,00
100,00
180,00
150,00
160,00
100,00
58,00
61,00
80,00
95,00
250,00
99,00
250,00
250,00
350,00

0
1
0
1
0
0
1
0
0
1
1
1
1
0
0
0
1
0
1
1

gruppo 1 singola avg=133,57 count=14

gruppo 2 doppia avg=165,89 count=9

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 luguale).
passo 5 Vengono proiettati gli attributi in select.
PrezzoMedio
133,57
165,89

COUNT(S.tipo)
14
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 allindice

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
FROM
WHERE
GROUP BY
HAVING

P.codHotel, COUNT(*) AS NumeroPrenotazioni


prenotazione P
P.dataInizio < 2015-07-10
P.codHotel
NumeroPrenotazioni > 10

passo 1 Viene applicata la condizione where dataInizio < 2015-07-10 alla tabella
prenotazione.
numStanza
1
1
2
55
3
55
58
4
22
4
5
1

codHotel
100
100
110
140
100
140
140
120
130
150
150
120

idCliente
2
4
1
3
4
5
6
7
1
3
4
2

data Inizio
2013-07-14
2013-08-10
2013-07-02
2013-08-20
2013-09-01
2013-09-12
2013-07-01
2014-05-10
2014-06-05
2015-03-01
2015-03-15
2015-05-20

dataFine
2013-07-20
2013-08-20
2013-07-09
2013-08-28
2013-09-18
2013-09-30
2013-07-15
2014-05-20
2014-06-15

passo 2 Viene eseguito il raggruppamento sul campo codHotel della tabella


prenotazione.
...
...
...
...
...

codHotel
100
100
100
110

...
...
...
...
...

data Inizio
2013-07-14
2013-08-10
2013-09-01
2013-07-02

...
...
...
...
...

...
...
...

120
120
130

...
...
...

2014-05-10
2015-05-20
2014-06-05

...
...
...

...
...
...
...
...

140
140
140
150
150

...
...
...
...
...

2013-08-20
2013-09-12
2013-07-01
2015-03-01
2015-03-15

...
...
...
...
...

gruppo 1 codH 100

gruppo 2 codH 110


gruppo 3 codH 120
gruppo 4 codH 130

gruppo 5 codH 140


gruppo 6 codH 150

65

Bocchi Cinzia 03/01/2015

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


...
...
...
...
...

codHotel
100
100
100
110

...
...
...
...
...

data Inizio
2013-07-14
2013-08-10
2013-09-01
2013-07-02

...
...
...
...
...

...
...
...

120
120
130

...
...
...

2014-05-10
2015-05-20
2014-06-05

...
...
...

...
...
...
...
...

140
140
140
150
150

...
...
...
...
...

2013-08-20
2013-09-12
2013-07-01
2015-03-01
2015-03-15

...
...
...
...
...

gruppo 1 codH 100 count=3

gruppo 2 codH 110 count=1


gruppo 3 codH 120 count=2
gruppo 4 codH 130 count=1

gruppo 5 codH 140 count=3


gruppo 6 codH 150 count=2

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
100
100
100
120
120
140
140
140
150
150

...
...
...
...
...
...
...
...
...
...
...

data Inizio
2013-07-14
2013-08-10
2013-09-01
2014-05-10
2015-05-20
2013-08-20
2013-09-12
2013-07-01
2015-03-01
2015-03-15

...
...
...
...
...
...
...
...
...
...
...

gruppo 1 codH 100 count=3

gruppo 3 codH 120 count=2

gruppo 5 codH 140 count=3


gruppo 6 codH 150 count=2

passo 5 Vengono proiettati gli attributi in select.


codHotel
100
120
140
150

NumeroPrenotazioni
3
2
3
2

torna allindice

66

Bocchi Cinzia 03/01/2015

Prima alternativa corretta ma non ottimizzata


SELECT
FROM
WHERE
GROUP BY
HAVING

H.codHotel, COUNT(*) AS NumeroPrenotazioni


prenotazione P, hotel H
P.codHotel = H.codHotel AND P.dataInizio < 2015-07-10
H.codHotel
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
100
120
140
150

NumeroPrenotazioni
3
2
3
2

torna allindice

Seconda alternativa corretta ma non ottimizzata


SELECT
FROM
WHERE
GROUP BY
HAVING

S.codHotel, COUNT(*) AS NumeroPrenotazioni


prenotazione P, stanza S
P.codHotel = S.codHotel AND P.dataInizio < 2015-07-10
S.codHotel
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
100
120
140
150

NumeroPrenotazioni
3
2
3
2

torna allindice

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
FROM
WHERE
GROUP BY

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


prenotazione P, hotel H, cliente C
P.codHotel = H.codHotel AND P.idCliente = C.idCliente AND P.dataInizio
BETWEEN 2015-07-10 AND 2015-07-20 AND C.citta = Roma
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
Hote
l

idC
lien
te

data Inizio

...

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

100
100
110
140
100
140
140
120
130
150
150
120
150
150
150
100
100
110

2
4
1
3
4
5
6
7
1
3
4
2
3
5
6
7
4
2

2013-07-14
2013-08-10
2013-07-02
2013-08-20
2013-09-01
2013-09-12
2013-07-01
2014-05-10
2014-06-05
2015-03-01
2015-03-15
2015-05-20
2015-07-12
2015-07-20
2015-07-15
2015-07-13
2015-07-19
2015-07-11

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

cod
Hote
l
100
100
110
140
100
140
140
120
130
150
150
120
150
150
150
100
100
110

nome

citta

idC
lien
te

...

citt

Miramare
Miramare
Marittimo
Fiesta
Miramare
Fiesta
Fiesta
La baita
Miramare
Fiesta
Fiesta
La baita
Fiesta
Fiesta
Fiesta
Miramare
Miramare
Marittimo

Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Rimini
Aosta
Napoli
Torino
Torino
Aosta
Torino
Torino
Torino
Rimini
Rimini
Rimini

2
4
1
3
4
5
6
7
1
3
4
2
3
5
6
7
4
2

...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...
...

Milano
Catania
Torino
Roma
Catania
Roma
Roma
Roma
Torino
Roma
Catania
Milano
Roma
Roma
Roma
Roma
Catania
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
Hote
l

idC
lien
te

data Inizio

...

...
...
...
...
...
...

150
150
150
100
100
110

3
5
6
7
4
2

2015-07-12
2015-07-20
2015-07-15
2015-07-13
2015-07-19
2015-07-11

...
...
...
...
...
...

cod
Hote
l
150
150
150
100
100
110

nome

citta

idC
lien
te

...

citt

Fiesta
Fiesta
Fiesta
Miramare
Miramare
Marittimo

Torino
Torino
Torino
Rimini
Rimini
Rimini

3
5
6
7
4
2

...
...
...
...
...
...

Roma
Roma
Roma
Roma
Catania
Milano

68

Bocchi Cinzia 03/01/2015

passo 4 viene applicata la condizione C.citta = Roma.


...

cod
Hote
l

idC
lien
te

data Inizio

...

...
...
...
...

150
150
150
100

3
5
6
7

2015-07-12
2015-07-20
2015-07-15
2015-07-13

...
...
...
...

cod
Hote
l
150
150
150
100

nome

citta

idC
lien
te

...

citt

Fiesta
Fiesta
Fiesta
Miramare

Torino
Torino
Torino
Rimini

3
5
6
7

...
...
...
...

Roma
Roma
Roma
Roma

passo 5 Viene eseguito il raggruppamento sui campi citta e codHotel della tabella
hotel.
... cod
Hot
el
... 150
... 150
... 150
... 100

nome

citta

...

Fiesta
Fiesta
Fiesta
Miramare

Torino
Torino
Torino
Rimini

...
...
...
...

gruppo 1 Fiesta Torino

gruppo 2 Miramare Rimini

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


... cod
Hot
el
... 150
... 150
... 150
... 100

nome

citta

...

Fiesta
Fiesta
Fiesta
Miramare

Torino
Torino
Torino
Rimini

...
...
...
...

gruppo 1 Fiesta Torino count=3

gruppo 2 Miramare Rimini count= 1

passo 7 Vengono proiettati i campi in select.


citta
Torino
Rimini

codHotel
150
100

NumeroPrenotazioni
3
1

torna allindice

69

Bocchi Cinzia 03/01/2015

Alternativa corretta solo se non esistono hotel omonimi nella stessa citt
SELECT
FROM
WHERE
GROUP BY

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


prenotazione P, hotel H, cliente C
P.codHotel = H.codHotel AND P.idCliente = C.idCliente AND P.dataInizio
BETWEEN 2015-07-10 AND 2015-07-20 AND C.citta = Roma
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 allindice

Alternativa corretta ma non ottimizzata


SELECT
FROM
WHERE

GROUP BY

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


prenotazione P, hotel H, cliente C, stanza S
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
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 allindice

Prima alternativa errata


SELECT
FROM
WHERE
GROUP BY

H.citta, COUNT(*) AS NumeroPrenotazioni


prenotazione P, hotel H, cliente C
P.codHotel = H.codHotel AND P.idCliente = C.idCliente AND P.dataInizio
BETWEEN 2015-07-10 AND 2015-07-20 AND C.citta = Roma
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 allindice

70

Bocchi Cinzia 03/01/2015

Seconda alternativa errata


SELECT
FROM
WHERE
GROUP BY

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


prenotazione P, hotel H, cliente C
P.codHotel = H.codHotel AND P.idCliente = C.idCliente AND P.dataInizio
BETWEEN 2015-07-10 AND 2015-07-20 AND C.citta = Roma
H.citta

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

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