Queer European MD passionate about IT

queries.tex 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. % !TEX root = ../main.tex
  2. \begin{enumerate}[label=\alph*.]
  3. \item Uso di proiezione, join e restrizione.
  4. Mostrare l'IdRicetta e il Nome delle ricette create da birrai di nome
  5. Giovanni.
  6. \begin{lstlisting}[style=SQLu,escapechar=@]
  7. SELECT r.IdRicetta, r.Nome
  8. FROM Ricette r
  9. JOIN Persone p ON p.IdPersona = r.IdCreatrice
  10. WHERE p.Nome = 'Giovanni'
  11. \end{lstlisting}
  12. \item Uso di group by con having, where e sort.
  13. Per ogni birrificio che abbia fatto almeno un acquisto quest'anno,
  14. riportare l'IdBirrificio e il numero di diversi fornitori da cui ha
  15. acquistato quest'anno, se questo numero è almeno di 3.
  16. Ordinare il risultato dal birrificio che ha avuto più fornitori a quello
  17. che ne ha avuti meno.
  18. \begin{lstlisting}[style=SQLu,escapechar=@]
  19. SELECT fa.IdBirrificio,
  20. COUNT(DISTINCT fa.IdFornitore) DiversiFornitori
  21. FROM Fatture fa
  22. WHERE fa.Data >= '2020-01-01'
  23. GROUP BY fa.IdBirrificio
  24. HAVING COUNT(DISTINCT fa.IdFornitore) >= 3
  25. ORDER BY COUNT(DISTINCT fa.IdFornitore) DESC
  26. \end{lstlisting}
  27. \item Uso di join, group by con having e where.
  28. Dei fornitori da cui ha ordinato il birrificio `Pirati Rossi', mostrare la
  29. ragione sociale, l'importo totale e l'importo medio delle fatture, purché
  30. l'importo totale sia superiore a 10 euro.
  31. \begin{lstlisting}[style=SQLu,escapechar=@]
  32. SELECT fo.RagioneSociale, SUM(fa.Importo) ImportoTotale,
  33. AVG(fa.Importo) ImportoMedio
  34. FROM Fornitori fo
  35. JOIN Fatture fa ON fa.IdFornitore = fo.IdFornitore
  36. JOIN Birrifici b ON b.IdBirrificio = fa.IdBirrificio
  37. WHERE b.Nome = 'Pirati Rossi'
  38. GROUP BY fo.IdFornitore, fo.RagioneSociale
  39. HAVING SUM(fa.Importo) > 10
  40. \end{lstlisting}
  41. \item Uso di select annidata con quantificazione esistenziale.
  42. Mostrare il soprannome de* birrai* che siano aut*r* di almeno una ricetta.
  43. \begin{lstlisting}[style=SQLu,escapechar=@]
  44. SELECT b.Soprannome
  45. FROM Birraie b
  46. WHERE EXISTS (SELECT *
  47. FROM Ricette r
  48. WHERE r.IdCreatrice = b.IdPersona)
  49. \end{lstlisting}
  50. \clearpage
  51. \item Uso di select annidata con quantificazione universale.
  52. Mostrare il nome e il cognome de* clienti che hanno ordinato da un solo
  53. birrificio.
  54. \textbf{Traduco in notazione insiemistica:}
  55. \begin{lstlisting}[style=SQLu,escapechar=@]
  56. {p1.Nome, p1.Cognome | (p1 @$\in$@ Persone, pre1 @$\in$@ Prenotazioni,
  57. pre1.IdCliente = p1.IdPersona,
  58. pro1 @$\in$@ Produzioni,
  59. pro1.IdProduzione = pre1.IdProduzione,
  60. r1 @$\in$@ Ricette,
  61. r1.IdRicetta = pro1.IdRicetta) .
  62. @$\forall$@ (pre2 @$\in$@ Prenotazioni, pre2.IdCliente = pre1.IdCliente
  63. pro2 @$\in$@ Produzioni, pro2.IdProduzione = pre2.IdProduzione,
  64. r2 @$\in$@ Ricette, r2.IdRicetta = pro2.IdRicetta) .
  65. (r2.IdBirrificio = r1.IdBirrificio)}
  66. \end{lstlisting}
  67. \textbf{Sostituisco il $\forall x . P$ con $\neg\exists x . \neg P$}
  68. \begin{lstlisting}[style=SQLu,escapechar=@]
  69. {p1.Nome, p1.Cognome | (p1 @$\in$@ Persone, pre1 @$\in$@ Prenotazioni,
  70. pre1.IdCliente = p1.IdPersona,
  71. pro1 @$\in$@ Produzioni,
  72. pro1.IdProduzione = pre1.IdProduzione,
  73. r1 @$\in$@ Ricette,
  74. r1.IdRicetta = pro1.IdRicetta) .
  75. @$\neg\exists$@ (pre2 @$\in$@ Prenotazioni, pre2.IdCliente = pre1.IdCliente
  76. pro2 @$\in$@ Produzioni, pro2.IdProduzione = pre2.IdProduzione,
  77. r2 @$\in$@ Ricette, r2.IdRicetta = pro2.IdRicetta) .
  78. (r2.IdBirrificio @$\neq$@ r1.IdBirrificio)}
  79. \end{lstlisting}
  80. \textbf{Scrivo quindi la query}, inserendo l'\texttt{IdPersona} e la parola chiave
  81. \texttt{DISTINCT} per rimuovere i duplicati (ma non le persone omonime).
  82. \begin{lstlisting}[style=SQLu,escapechar=@]
  83. SELECT DISTINCT p1.IdPersona, p1.Nome, p1.Cognome
  84. FROM Persone p1
  85. JOIN Prenotazioni pre1 ON pre1.IdCliente = p1.IdPersona
  86. JOIN Produzioni pro1 ON pro1.IdProduzione = pre1.IdProduzione
  87. JOIN Ricette r1 ON r1.IdRicetta = pro1.IdRicetta
  88. WHERE NOT EXISTS (SELECT *
  89. FROM Prenotazioni pre2
  90. JOIN Produzioni pro2
  91. ON pro2.IdProduzione = pre2.IdProduzione
  92. JOIN Ricette r2 ON r2.IdRicetta = pro2.IdRicetta
  93. WHERE pre2.IdCliente = pre1.IdCliente
  94. AND r2.IdBirrificio <> r1.IdBirrificio)
  95. \end{lstlisting}
  96. \item Uso di subquery di confronto quantificato.
  97. Per ogni birrificio, mostrare l'IdBirrificio e l'ultimo NumeroLotto
  98. prodotto in quel birrificio (sapendo che il NumeroLotto è progressivo).
  99. \begin{lstlisting}[style=SQLu,escapechar=@]
  100. SELECT r1.IdBirrificio, pro1.NumeroLotto
  101. FROM Produzioni pro1
  102. JOIN Ricette r1 ON r1.IdRicetta = pro1.IdRicetta
  103. WHERE pro1.NumeroLotto >= ANY (SELECT pro2.NumeroLotto
  104. FROM Produzioni pro2
  105. JOIN Ricette r2
  106. ON r2.IdRicetta = pro2.IdRicetta
  107. WHERE r2.IdBirrificio = r1.IdBirrificio)
  108. \end{lstlisting}
  109. \end{enumerate}
  110. \clearpage