Advertisement
Guest User

Untitled

a guest
Feb 21st, 2020
214
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.73 KB | None | 0 0
  1.  
  2. /* EXEMPLE */
  3. -- extensia ROLLUP
  4.  
  5. -- Afisati numele departamentului, numele meseriei, salarul minim, salarul maxim si media
  6. -- salarului pentru meserie, respectiv departament. Sa se afiseze si valorile agregate la nivel de
  7. -- meserie, la nivel de department si la nivel general. Ordonati liniile dupa numele departamentului
  8. -- si apoi dupa numele meseriei.
  9. SELECT dname, job, AVG(sal), MIN(sal), MAX(sal)
  10. FROM emp e, dept d
  11. WHERE e.deptno = d.deptno
  12. GROUP BY ROLLUP(dname, job)
  13. ORDER BY dname, job;
  14.  
  15. -- doar cu clauza GROUP BY
  16. SELECT dname, job, AVG(sal), MIN(sal), MAX(sal)
  17. FROM emp e, dept d
  18. WHERE e.deptno = d.deptno
  19. GROUP BY dname, job
  20. ORDER BY dname, job;
  21.  
  22. -- ROLLUP partial
  23. SELECT loc, dname, job, AVG(sal), MIN(sal), MAX(sal)
  24. FROM emp e, dept d
  25. WHERE e.deptno = d.deptno
  26. GROUP BY loc, ROLLUP(dname, job);
  27.  
  28. -- extensia CUBE
  29.  
  30. -- Afisati numele departamentului, numele meseriei, precum si toate valorile pentru salarul
  31. -- minim, salarul maxim si media salarului pentru meserie, respectiv departament. Sa se afiseze si
  32. -- valorile agregate la nivel de meserie, la nivel de department, la nivel de meserie si departament,
  33. -- precum si la nivel general.
  34. SELECT dname, job, AVG(sal), MIN(sal), MAX(sal)
  35. FROM emp e, dept d
  36. WHERE e.deptno = d.deptno
  37. GROUP BY CUBE(dname, job);
  38.  
  39. -- CUBE partial = ROLLUP() pentru toate combinatiile de dimensiuni
  40. SELECT loc, dname, job, AVG(sal), MIN(sal), MAX(sal)
  41. FROM emp e, dept d
  42. WHERE e.deptno = d.deptno
  43. GROUP BY loc, CUBE(dname, job);
  44.  
  45. -- GROUPING -> pentru a afla daca valorile de NULL provin din ROLLUP / CUBE sau din tabela initiala
  46. SELECT dname, job, ROUND(AVG(sal), 2), MIN(sal), MAX(sal),
  47. GROUPING(dname) AS gdept, GROUPING(job) AS gjob
  48. FROM emp e, dept d
  49. WHERE e.deptno = d.deptno
  50. GROUP BY ROLLUP(dname, job);
  51.  
  52. SELECT dname, job, AVG(sal), MIN(sal), MAX(sal),
  53. GROUPING(dname) AS gdept, GROUPING(job) AS gjob
  54. FROM emp e, dept d
  55. WHERE e.deptno = d.deptno
  56. GROUP BY CUBE(dname, job)
  57. HAVING GROUPING(dname) = 1 OR GROUPING(job) = 1;
  58.  
  59. -- GROUPING_ID -> pentru a afla nivelul de agregare
  60. SELECT dname, job, AVG(sal), MIN(sal), MAX(sal),
  61. GROUPING(dname) AS gdept, GROUPING(job) AS gjob,
  62. GROUPING_ID(dname, job) AS nivel
  63. FROM emp e, dept d
  64. WHERE e.deptno = d.deptno
  65. GROUP BY CUBE(dname, job)
  66. ORDER BY nivel;
  67.  
  68. -- GROUP_ID -> pentru a afla duplicatele
  69. SELECT dname, job, AVG(sal), 2,
  70. GROUPING(dname) AS gdept, GROUPING(job) AS gjob,
  71. GROUPING_ID(dname, job) AS nivel, GROUP_ID()
  72. FROM emp e, dept d
  73. WHERE e.deptno = d.deptno
  74. GROUP BY dname, ROLLUP(dname, job)
  75. ORDER BY nivel;
  76.  
  77. -- GROUPING SETS
  78. -- Calculati salarul mediu pentru doua grupuri de date: department / job si job/manager
  79. SELECT dname, job, mgr, avg(sal)
  80. FROM emp e, dept d
  81. WHERE e.deptno = d.deptno
  82. GROUP BY GROUPING SETS((dname, job), (job, mgr));
  83.  
  84. /* EXERCITII */
  85. -- 1
  86. SELECT job, grade, ROUND(AVG(sal), 2), MIN(sal), MAX(sal), SUM(sal)
  87. FROM emp JOIN salgrade
  88. ON emp.sal BETWEEN losal AND hisal -- gradul de salarizare = non-equijoin intre tabelele "emp" si "salgrade"
  89. GROUP BY ROLLUP(job, grade); -- calculul de subtotaluri -> ROLLUP()
  90.  
  91. -- 2
  92. SELECT job, grade, ROUND(AVG(sal), 2), MIN(sal), MAX(sal), SUM(sal)
  93. FROM emp JOIN salgrade
  94. ON emp.sal BETWEEN losal AND hisal
  95. GROUP BY CUBE(job, grade); -- subtotaluri intre toate combinatiile de cele 2 dimensiuni = in loc de ROLLUP() folosim CUBE()
  96.  
  97. -- 3
  98. SELECT e2.ename AS manager, e1.job, SUM(e1.sal), AVG(e1.sal), MIN(e1.sal), MAX(e1.sal)
  99. FROM emp e1 JOIN emp e2 ON e1.mgr = e2.empno -- pentru a afla managerul, facem self-join cu tabela "emp"
  100. GROUP BY ROLLUP(e2.ename, e1.job); -- e2.ename = manager
  101.  
  102. -- 4
  103. -- pentru a inlocui valorile de NULL folosim functia NVL()
  104. SELECT NVL(e2.ename, 'Total ename') AS manager, NVL(e1.job, 'Total job') AS job,
  105. SUM(e1.sal), AVG(e1.sal), MIN(e1.sal), MAX(e1.sal)
  106. FROM emp e1 JOIN emp e2 ON e1.mgr = e2.empno
  107. GROUP BY ROLLUP(e2.ename, e1.job);
  108.  
  109. -- 5
  110. SELECT NVL(d.dname, 'Total') AS dname, NVL(e1.job, 'Total') AS job,
  111. NVL(e2.ename, 'Total') AS manager, NVL(TO_CHAR(s.grade), 'Total') AS grade,
  112. SUM(e1.sal),
  113. GROUPING_ID(d.dname, e1.job, e2.ename, s.grade) AS nivel_agregare -- functia GROUPING_ID() ne da nivelul de agregare
  114. FROM emp e1 JOIN emp e2 ON e1.mgr = e2.empno -- SELF JOIN intre emp si emp (pentru a afla manager-ul)
  115. JOIN dept d ON e1.deptno = d.deptno -- EQUIJOIN intre emp si dept
  116. JOIN salgrade s ON e1.sal BETWEEN losal AND hisal -- aflarea gradului de salarizare: NON-EQUIJOIN intre emp si salgrade
  117. GROUP BY GROUPING SETS(ROLLUP(d.dname, e1.job), ROLLUP(e2.ename, s.grade))
  118. HAVING GROUP_ID() = 0 -- evitarea duplicatelor -> eliminam inregistrarile cu GROUP_ID() nenul
  119. ORDER BY GROUPING_ID(d.dname, e1.job, e2.ename, s.grade) ASC;
  120.  
  121. -- 6
  122. SELECT ch.channel_desc, t.calendar_month_desc, cust.country_id, SUM(s.amount_sold)
  123. FROM sales s JOIN channels ch ON (s.channel_id = ch.channel_id)
  124. JOIN times t ON (s.time_id = t.time_id)
  125. JOIN customers cust ON (s.cust_id = cust.cust_id) -- JOIN cu tabela "customers" ca sa putem afla "country_id"
  126. JOIN countries c ON (cust.country_id = c.country_id)
  127. -- sales = tabela de fapte, restul sunt tabele de dimensiune
  128. WHERE ch.channel_desc IN ('Direct Sales', 'Internet') -- aplicam filtrarile cerute in enunt
  129. AND t.calendar_month_desc IN ('2000-09', '2000-10')
  130. AND cust.country_id IN ('UK', 'US')
  131. GROUP BY ROLLUP(ch.channel_desc, t.calendar_month_desc, cust.country_id); -- subtotalurile pe coloanele cerute
  132.  
  133. -- 7
  134. SELECT ch.channel_desc, t.calendar_month_desc, cust.country_id, SUM(s.amount_sold)
  135. FROM sales s JOIN channels ch ON (s.channel_id = ch.channel_id)
  136. JOIN times t ON (s.time_id = t.time_id)
  137. JOIN customers cust ON (s.cust_id = cust.cust_id)
  138. JOIN countries c ON (cust.country_id = c.country_id)
  139. WHERE ch.channel_desc IN ('Direct Sales', 'Internet')
  140. AND t.calendar_month_desc IN ('2000-09', '2000-10')
  141. AND cust.country_id IN ('UK', 'US')
  142. GROUP BY ch.channel_desc, ROLLUP(t.calendar_month_desc, cust.country_id);
  143. -- singura modificare este in GROUP BY, unde scoatem campul "channel_desc" din ROLLUP(), pentru a obtine gruparea partiala
  144.  
  145. -- 8
  146. SELECT ch.channel_desc, t.calendar_month_desc, cust.country_id, SUM(s.amount_sold)
  147. FROM sales s JOIN channels ch ON (s.channel_id = ch.channel_id)
  148. JOIN times t ON (s.time_id = t.time_id)
  149. JOIN customers cust ON (s.cust_id = cust.cust_id)
  150. JOIN countries c ON (cust.country_id = c.country_id)
  151. WHERE ch.channel_desc IN ('Direct Sales', 'Internet')
  152. AND t.calendar_month_desc IN ('2000-09', '2000-10')
  153. AND cust.country_id IN ('UK', 'US')
  154. GROUP BY CUBE(ch.channel_desc, t.calendar_month_desc, cust.country_id);
  155. -- modificare fata de problema 6: folosim CUBE() in loc de ROLLUP(), pentru ca vrem subtotaluri pentru toate combinatiile de dimensiuni
  156.  
  157. SELECT NVL(ch.channel_desc, 'All channels'), NVL(cust.country_id, 'All countries'), SUM(s.amount_sold)
  158. -- valorile NULL se trateaza cu NVL()
  159. FROM sales s JOIN channels ch ON (s.channel_id = ch.channel_id)
  160. JOIN times t ON (s.time_id = t.time_id)
  161. JOIN customers cust ON (s.cust_id = cust.cust_id)
  162. JOIN countries c ON (cust.country_id = c.country_id)
  163. WHERE ch.channel_desc IN ('Direct Sales', 'Internet')
  164. AND t.calendar_month_desc IN ('2000-09', '2000-10')
  165. AND cust.country_id IN ('UK', 'US')
  166. GROUP BY CUBE(ch.channel_desc, cust.country_id);
  167. -- nu mai luam in considerare luna in calculul subtotalurilor (stergem si din CUBE() si din SELECT)
  168.  
  169. -- 9
  170. SELECT NVL(ch.channel_desc, 'All channels'), NVL(cust.country_id, 'All countries'), SUM(s.amount_sold)
  171. FROM sales s JOIN channels ch ON (s.channel_id = ch.channel_id)
  172. JOIN times t ON (s.time_id = t.time_id)
  173. JOIN customers cust ON (s.cust_id = cust.cust_id)
  174. JOIN countries c ON (cust.country_id = c.country_id)
  175. WHERE ch.channel_desc IN ('Direct Sales', 'Internet')
  176. AND t.calendar_month_desc IN ('2000-09', '2000-10')
  177. AND cust.country_id IN ('UK', 'US')
  178. GROUP BY ROLLUP(cust.country_id, ch.channel_desc); -- doar totalurile pe tara, respectiv pe canal (ROLLUP() + campuri inversate fata de problema 8)
  179.  
  180. -- 10
  181. SELECT ch.channel_desc, t.calendar_month_desc, cust.country_id, SUM(s.amount_sold)
  182. FROM sales s JOIN channels ch ON (s.channel_id = ch.channel_id)
  183. JOIN times t ON (s.time_id = t.time_id)
  184. JOIN customers cust ON (s.cust_id = cust.cust_id)
  185. JOIN countries c ON (cust.country_id = c.country_id)
  186. WHERE ch.channel_desc IN ('Direct Sales', 'Internet')
  187. AND t.calendar_month_desc IN ('2000-09', '2000-10')
  188. AND cust.country_id IN ('UK', 'US')
  189. -- in loc de ROLLUP() folosim GROUPING SETS pentru subtotaluri pe liste de grupuri specificate
  190. GROUP BY GROUPING SETS((ch.channel_desc, t.calendar_month_desc, cust.country_id),
  191. (ch.channel_desc, cust.country_id),
  192. (t.calendar_month_desc, cust.country_id));
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement