laboratorio di basi di dati · 2017. 5. 23. · laboratorio di basi di dati query in sql parte di...

32
Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina, Daniele Riboni e Sergio Mascetti Anno accademico 2016-2017 Paolo Perlasca

Upload: others

Post on 22-Aug-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

Laboratorio di Basi di Dati

Query in SQL

Parte di questi lucidi è tratta da una versione precedente di

Marco Mesiti, Stefano Valtolina, Daniele Riboni e Sergio Mascetti

Anno accademico 2016-2017

Paolo Perlasca

Page 2: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

2

Pizzeria “ProntoPizza”

Pizza(codP,nome,prezzo)

Ingrediente(codPPizza, ingrediente)

Cliente(telC,cognomeC,nomeC,via,nCiv,nInt)

Ordine(telCCliente,data,codPPizza,qta,importo)

Page 3: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

3

Query 1

!  Trovare i prezzi ed i nomi delle pizze che costano meno di 6 euro

SELECT prezzo, nome

FROM Pizza

WHERE prezzo < 6;

Page 4: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

4

Query 2

!  Trovare gli ingredienti delle pizze

SELECT DISTINCT ingrediente FROM Ingrediente;

Page 5: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

5

Query 3

!  Trovare il cognome, nome e telefono dei clienti che abitano in via dei Girasoli ordinati per cognome e nome

SELECT cognomeC, nomeC, telC FROM Cliente WHERE via = 'via dei Girasoli' ORDER BY cognomeC, nomeC;

Page 6: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

6

Query 4

!  Trovare il numero di telefono dei clienti che hanno effettuato un ordine di almeno 5 pizze nell'ultima settimana, spendendo tra i 20 e i 50 euro.

SELECT telC FROM Ordine WHERE qta >= 5 AND importo BETWEEN 20 AND 50 AND (CURRENT_DATE - data) < 7;

Page 7: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

7

Query 5

!  Trovare il nome delle pizze ordinate in data 4 settembre 2009

SELECT DISTINCT nome FROM Pizza NATURAL JOIN Ordine WHERE data ='2009-09-04';

Page 8: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

8

Query 6

Trovare i nominativi dei clienti che hanno ordinato almeno una pizza che contenga le olive di ogni genere (olive verdi, olive nere, pasta di olive ecc.), insieme alla data e all'importo dell'ordine. Presentare il risultato ordinato in modo decrescente rispetto all'importo e, a parità di importo, in modo crescente per cognome e nome.

SELECT DISTINCT nomeC, cognomeC, data, importo FROM Ingrediente NATURAL JOIN Ordine NATURAL JOIN Cliente WHERE ingrediente LIKE '%olive%' ORDER BY importo DESC, cognomeC, nomeC;

Page 9: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

9

Query 7

Trovare i clienti “vicini di casa”. Due clienti si dicono vicini se abitano nella stessa via e la differenza dei loro numeri civici è minore di 5.

SELECT c1.nomec, c1.cognomec, c2.nomec, c2.cognomec FROM cliente c1, cliente c2 WHERE c1.via=c2.via AND c1.nCiv - c2.nCiv BETWEEN 0 AND 5 AND c1.telc != c2.telc

Page 10: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

10

Query 8

!  Restituire i dati degli ordini per i quali si è applicato uno sconto (cioè gli ordini per cui l'importo è inferiore al valore ottenuto moltiplicando la quantità ordinata per il relativo prezzo della pizza). Riportare anche lo sconto effettuato.

SELECT telC, data, codP, qta, importo, (prezzo*qta)-importo AS sconto FROM Ordine NATURAL JOIN Pizza WHERE prezzo * qta > importo;

Page 11: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

11

Query 9 !  Produrre l'elenco, in ordine

alfabetico, dei clienti. Per quelli che hanno effettuato almeno un ordine, riportare nell'elenco le informazioni relative all'importo e alla data degli ordini effettuati. Gli ordini dello stesso cliente devono essere ordinati dalla data più recente.

SELECT cognomeC, nomeC, data, importo FROM Cliente NATURAL LEFT JOIN Ordine ORDER BY cognomeC, nomeC, data DESC;

Page 12: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

12

Query 10

!  Trovare il numero totale, l'importo totale e medio degli ordini dei clienti e quante pizze diverse hanno ordinato.

SELECT COUNT(*), SUM(importo), AVG(importo), COUNT(DISTINCT codP) FROM Ordine;

Page 13: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

13

Query 10 bis

!  Trovare per ogni cliente, il numero totale, l'importo totale e medio dei suoi ordini e quante pizze diverse ha ordinato.

SELECT telC, COUNT(*), SUM(importo), AVG(importo), COUNT(DISTINCT codP) FROM Ordine GOUP BY telC;

Page 14: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

14

Query 10 bis

SELECT telC, COUNT(*), SUM(importo), AVG(importo), COUNT(DISTINCT codP) FROM Ordine GROUP BY telC;

!  Trovare, per ogni cliente che abbia ordinato almeno una pizza, il numero totale, l'importo totale e medio dei suoi ordini e quante pizze diverse ha ordinato.

Page 15: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

15

Query 11

!  Trovare il nome delle pizze ordinate nel 2010 il cui importo totale ordinato sia stato inferiore alla somma del prezzo per la quantità ordinata.

SELECT nome FROM Ordine natural join pizza WHERE data between '2010-01-01' and '2010-12-31‘ and Importo < prezzo*qta

Page 16: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

16

Query 12

!  Trovare il codice delle pizze con almeno 3 ingredienti. Restituire anche il numero di ingredienti.

SELECT codP, COUNT(*) FROM Ingrediente GROUP BY codP HAVING COUNT(*) >= 3;

Page 17: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

17

Query 12 BIS

!  Trovare il codice delle pizze con il maggior numero di ingredienti. Restituire anche il numero di ingredienti.

SELECT codP, COUNT(*) FROM Ingrediente GROUP BY codP HAVING COUNT(*) >= ALL(SELECT COUNT(*) FROM Ingrediente GROUP BY codP);

Page 18: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

18

Query 13

!  Restituire in una singola colonna, cognome e nome dei clienti che hanno ordinato il minor numero di pizze margherita (ma almeno una).

Per passi: Trovare il codice del cliente che ha ordinato il minor numero di pizze margherita

SELECT telC FROM Cliente NATURAL JOIN Ordine NATURAL JOIN Pizza WHERE nome = 'margherita' GROUP BY telC HAVING SUM(qta) <= ALL (quantità di pizza margherita ordinata dai clienti della pizzeria);

Page 19: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

19

Query 13 !  Restituire in una singola colonna, cognome e

nome dei clienti che hanno ordinato il minor numero di pizze margherita (ma almeno una)

SELECT cognomeC || ' ' || nomeC AS Nominativo FROM Cliente NATURAL JOIN Ordine NATURAL JOIN Pizza WHERE nome = 'margherita' GROUP BY telC, cognomeC, nomeC HAVING SUM(qta)<=ALL( SELECT SUM(qta) FROM Cliente NATURAL JOIN Ordine NATURAL JOIN Pizza WHERE nome = 'margherita' GROUP BY telC)

Page 20: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

20

Query 13

!  Inserire un nuovo ordine da parte del cliente "0105553300" per 3 pizze "p001"

!  Restituire in una singola colonna, cognome e nome dei clienti che hanno ordinato il minor numero di pizze margherita (ma almeno una)

!  Soluzione alternativa: uso delle viste

CREATE VIEW OrdiniPizzeMargherita AS SELECT telC, cognomeC, nomeC, SUM(qta) AS qtaTotale FROM Cliente NATURAL JOIN Ordine NATURAL JOIN Pizza WHERE nome = 'margherita' GROUP BY telC, cognomeC, nomeC;

SELECT cognomeC || ' ' || nomeC FROM OrdiniPizzeMargherita WHERE qtaTotale <= (SELECT MAX(qtaTotale) FROM OrdiniPizzeMargherita);

Page 21: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

21

Query 14

!  Trovare i clienti che hanno ordinato (almeno una volta) la pizza capricciosa oppure ai quattro formaggi.

SELECT DISTINCT telC FROM Ordine NATURAL JOIN Pizza WHERE nome = 'capricciosa' OR nome = 'quattro formaggi';

Page 22: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

22

Query 14

SELECT telC FROM Ordine NATURAL JOIN Pizza WHERE nome = 'capricciosa' UNION SELECT telC FROM Ordine NATURAL JOIN Pizza WHERE nome = 'quattro formaggi';

!  Soluzione alternativa: uso degli operatori insiemistici

Page 23: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

23

Query 15

!  Trovare le pizze che contengono sia mozzarella sia olive usando gli operatori insiemistici

SELECT codP FROM Ingrediente WHERE ingrediente = 'mozzarella' INTERSECT SELECT codP FROM Ingrediente WHERE ingrediente = 'olive';

Page 24: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

24

Query 15

SELECT DISTINCT codP FROM Ingrediente WHERE ingrediente = 'mozzarella' AND codP IN (SELECT codP FROM Ingrediente WHERE ingrediente = 'olive');

!  Trovare le pizze che contengono sia mozzarella sia olive usando l'operatore IN

Page 25: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

25

Query 15

SELECT DISTINCT codP FROM Ingrediente I WHERE ingrediente = 'mozzarella' AND EXISTS (SELECT codP FROM Ingrediente WHERE ingrediente = 'olive' AND I.codP = codP);

!  Trovare le pizze che contengono sia mozzarella sia olive usando l'operatore EXISTS

Page 26: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

26

Query 16

!  Determinare il numero di telefono ed i cognome dei clienti che hanno fatto solo ordini superiori ai 7 euro.

Prima di svolgere questo esercizio aggiungi un nuovo ordine di 3 pizze margherita (per un totale di 12 euro) per l’utente di cognome Bianchi (telC = "0105554400").

Page 27: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

27

Query 16

!  Determinare i numeri di telefono ed i nominativi dei clienti che hanno fatto solo ordini superiori ai 7 euro usando operatori insiemistici

SELECT telC, nomeC, cognomeC FROM Cliente c NATURAL JOIN Ordine EXCEPT SELECT telC, nomeC, cognomeC FROM Cliente c NATURAL JOIN Ordine WHERE importo <= 7

Page 28: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

28

Query 16

!  Determinare i numeri di telefono ed i nominativi dei clienti che hanno fatto solo ordini superiori ai 7 euro usando variabili e NOT EXISTS.

SELECT telC, nomeC, cognomeC FROM Cliente c NATURAL JOIN ordine WHERE NOT EXISTS (SELECT * FROM Ordine WHERE importo <= 7 AND telC = c.telC);

Page 29: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

29

Query 16

!  Determinare i numeri di telefono ed i nominativi dei clienti che hanno fatto solo ordini superiori ai 7 euro usando NOT IN.

SELECT telC, nomeC, cognomeC FROM Cliente NATURAL JOIN Ordine WHERE telC NOT IN (SELECT telC FROM Ordine WHERE importo <= 7);

Page 30: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

30

Query 17

!  Determinare quali pizze sono state ordinate da tutti i clienti.

L'interrogazione può essere riscritta come:

determinare la pizza per la quale non esiste un cliente che non l'abbia ordinata.

Page 31: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

31

Query 17

SELECT * FROM Pizza p WHERE NOT EXISTS (cliente che non abbia ordinato p);

SELECT * FROM Pizza p WHERE NOT EXISTS (SELECT * FROM Cliente WHERE telC NOT IN (SELECT telC FROM Ordine WHERE codP = p.codP));

Page 32: Laboratorio di Basi di Dati · 2017. 5. 23. · Laboratorio di Basi di Dati Query in SQL Parte di questi lucidi è tratta da una versione precedente di Marco Mesiti, Stefano Valtolina,

32

Query 17

SELECT codp FROM ordine Group by codp Having count(distinct telc)=(select count(distinct telc)

from cliente);