Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
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 2017-2018
Paolo Perlasca
2
Pizzeria “ProntoPizza”
Pizza(codP,nome,prezzo)
Ingrediente(codPPizza, ingrediente)
Cliente(telC,cognomeC,nomeC,via,nCiv,nInt)
Ordine(telCCliente,data,codPPizza,qta,importo)
3
Query 1
n Trovare i prezzi ed i nomi delle pizze che costano meno di 6 euro
SELECT prezzo, nome
FROM Pizza
WHERE prezzo < 6;
4
Query 2
n Trovare gli ingredienti delle pizze
SELECT DISTINCT ingrediente FROM Ingrediente;
5
Query 3
n 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;
6
Query 4
n 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;
7
Query 5
n Trovare il nome delle pizze ordinate in data 4 settembre 2009
SELECT DISTINCT nome FROM Pizza NATURAL JOIN Ordine WHERE data ='2009-09-04';
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;
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
10
Query 8
n 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;
11
Query 9 n 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;
12
Query 10
n 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;
13
Query 10 bis
n 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;
14
Query 10 bis
SELECT telC, COUNT(*), SUM(importo), AVG(importo), COUNT(DISTINCT codP) FROM Ordine GROUP BY telC;
n 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.
15
Query 11
n 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
16
Query 12
n 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;
17
Query 12 BIS
n 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);
18
Query 13
n 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);
19
Query 13 n 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)
20
Query 14
n 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';
21
Query 14
SELECT telC FROM Ordine NATURAL JOIN Pizza WHERE nome = 'capricciosa' UNION SELECT telC FROM Ordine NATURAL JOIN Pizza WHERE nome = 'quattro formaggi';
n Soluzione alternativa: uso degli operatori insiemistici
22
Query 15
n 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';
23
Query 15
SELECT DISTINCT codP FROM Ingrediente WHERE ingrediente = 'mozzarella' AND codP IN (SELECT codP FROM Ingrediente WHERE ingrediente = 'olive');
n Trovare le pizze che contengono sia mozzarella sia olive usando l'operatore IN
24
Query 15
SELECT DISTINCT codP FROM Ingrediente I WHERE ingrediente = 'mozzarella' AND EXISTS (SELECT codP FROM Ingrediente WHERE ingrediente = 'olive' AND I.codP = codP);
n Trovare le pizze che contengono sia mozzarella sia olive usando l'operatore EXISTS
25
Query 16
n 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").
26
Query 16
n 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
27
Query 16
n 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);
28
Query 16
n 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);
29
Query 17
n 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.
30
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));
31
Query 17
SELECT codp FROM ordine Group by codp Having count(distinct telc)=(select count(distinct telc)
from cliente);