123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- % !TEX root = ../main.tex
- \begin{enumerate}[label=\alph*.]
- \item Uso di proiezione, join e restrizione.
- Mostrare l'IdRicetta e il Nome delle ricette create da birrai di nome
- Giovanni.
- \begin{lstlisting}[style=SQLu,escapechar=@]
- SELECT r.IdRicetta, r.Nome
- FROM Ricette r
- JOIN Persone p ON p.IdPersona = r.IdCreatrice
- WHERE p.Nome = 'Giovanni'
- \end{lstlisting}
- \item Uso di group by con having, where e sort.
- Per ogni birrificio che abbia fatto almeno un acquisto quest'anno,
- riportare l'IdBirrificio e il numero di diversi fornitori da cui ha
- acquistato quest'anno, se questo numero è almeno di 3.
- Ordinare il risultato dal birrificio che ha avuto più fornitori a quello
- che ne ha avuti meno.
- \begin{lstlisting}[style=SQLu,escapechar=@]
- SELECT fa.IdBirrificio,
- COUNT(DISTINCT fa.IdFornitore) DiversiFornitori
- FROM Fatture fa
- WHERE fa.Data >= '2020-01-01'
- GROUP BY fa.IdBirrificio
- HAVING COUNT(DISTINCT fa.IdFornitore) >= 3
- ORDER BY COUNT(DISTINCT fa.IdFornitore) DESC
- \end{lstlisting}
- \item Uso di join, group by con having e where.
- Dei fornitori da cui ha ordinato il birrificio `Pirati Rossi', mostrare la
- ragione sociale, l'importo totale e l'importo medio delle fatture, purché
- l'importo totale sia superiore a 10 euro.
- \begin{lstlisting}[style=SQLu,escapechar=@]
- SELECT fo.RagioneSociale, SUM(fa.Importo) ImportoTotale,
- AVG(fa.Importo) ImportoMedio
- FROM Fornitori fo
- JOIN Fatture fa ON fa.IdFornitore = fo.IdFornitore
- JOIN Birrifici b ON b.IdBirrificio = fa.IdBirrificio
- WHERE b.Nome = 'Pirati Rossi'
- GROUP BY fo.IdFornitore, fo.RagioneSociale
- HAVING SUM(fa.Importo) > 10
- \end{lstlisting}
- \item Uso di select annidata con quantificazione esistenziale.
- Mostrare il soprannome de* birrai* che siano aut*r* di almeno una ricetta.
- \begin{lstlisting}[style=SQLu,escapechar=@]
- SELECT b.Soprannome
- FROM Birraie b
- WHERE EXISTS (SELECT *
- FROM Ricette r
- WHERE r.IdCreatrice = b.IdPersona)
- \end{lstlisting}
- \clearpage
- \item Uso di select annidata con quantificazione universale.
- Mostrare il nome e il cognome de* clienti che hanno ordinato da un solo
- birrificio.
- \textbf{Traduco in notazione insiemistica:}
- \begin{lstlisting}[style=SQLu,escapechar=@]
- {p1.Nome, p1.Cognome | (p1 @$\in$@ Persone, pre1 @$\in$@ Prenotazioni,
- pre1.IdCliente = p1.IdPersona,
- pro1 @$\in$@ Produzioni,
- pro1.IdProduzione = pre1.IdProduzione,
- r1 @$\in$@ Ricette,
- r1.IdRicetta = pro1.IdRicetta) .
- @$\forall$@ (pre2 @$\in$@ Prenotazioni, pre2.IdCliente = pre1.IdCliente
- pro2 @$\in$@ Produzioni, pro2.IdProduzione = pre2.IdProduzione,
- r2 @$\in$@ Ricette, r2.IdRicetta = pro2.IdRicetta) .
- (r2.IdBirrificio = r1.IdBirrificio)}
- \end{lstlisting}
- \textbf{Sostituisco il $\forall x . P$ con $\neg\exists x . \neg P$}
- \begin{lstlisting}[style=SQLu,escapechar=@]
- {p1.Nome, p1.Cognome | (p1 @$\in$@ Persone, pre1 @$\in$@ Prenotazioni,
- pre1.IdCliente = p1.IdPersona,
- pro1 @$\in$@ Produzioni,
- pro1.IdProduzione = pre1.IdProduzione,
- r1 @$\in$@ Ricette,
- r1.IdRicetta = pro1.IdRicetta) .
- @$\neg\exists$@ (pre2 @$\in$@ Prenotazioni, pre2.IdCliente = pre1.IdCliente
- pro2 @$\in$@ Produzioni, pro2.IdProduzione = pre2.IdProduzione,
- r2 @$\in$@ Ricette, r2.IdRicetta = pro2.IdRicetta) .
- (r2.IdBirrificio @$\neq$@ r1.IdBirrificio)}
- \end{lstlisting}
- \textbf{Scrivo quindi la query}, inserendo l'\texttt{IdPersona} e la parola chiave
- \texttt{DISTINCT} per rimuovere i duplicati (ma non le persone omonime).
- \begin{lstlisting}[style=SQLu,escapechar=@]
- SELECT DISTINCT p1.IdPersona, p1.Nome, p1.Cognome
- FROM Persone p1
- JOIN Prenotazioni pre1 ON pre1.IdCliente = p1.IdPersona
- JOIN Produzioni pro1 ON pro1.IdProduzione = pre1.IdProduzione
- JOIN Ricette r1 ON r1.IdRicetta = pro1.IdRicetta
- WHERE NOT EXISTS (SELECT *
- FROM Prenotazioni pre2
- JOIN Produzioni pro2
- ON pro2.IdProduzione = pre2.IdProduzione
- JOIN Ricette r2 ON r2.IdRicetta = pro2.IdRicetta
- WHERE pre2.IdCliente = pre1.IdCliente
- AND r2.IdBirrificio <> r1.IdBirrificio)
- \end{lstlisting}
- \item Uso di subquery di confronto quantificato.
- Per ogni birrificio, mostrare l'IdBirrificio e l'ultimo NumeroLotto
- prodotto in quel birrificio (sapendo che il NumeroLotto è progressivo).
- \begin{lstlisting}[style=SQLu,escapechar=@]
- SELECT r1.IdBirrificio, pro1.NumeroLotto
- FROM Produzioni pro1
- JOIN Ricette r1 ON r1.IdRicetta = pro1.IdRicetta
- WHERE pro1.NumeroLotto >= ANY (SELECT pro2.NumeroLotto
- FROM Produzioni pro2
- JOIN Ricette r2
- ON r2.IdRicetta = pro2.IdRicetta
- WHERE r2.IdBirrificio = r1.IdBirrificio)
- \end{lstlisting}
- \end{enumerate}
- \clearpage
|