<div class="page"> <div class="cover text-center"> <img class="mx-auto" src=/itb/images/logo_mislata.png alt="logo"> # Agrupació <div class="text-end fit-content ms-auto my-3 mt-auto pt-3"> <p><strong>Autor:</strong> Joan Puigcerver Ibáñez</p> <p><strong>Correu electrònic:</strong> j.puigcerveribanez@edu.gva.es</p> <p><strong>Curs:</strong> 2023/2024</p> </div> <div> <p class="fw-bold mb-0">Llicència: BY-NC-SA</p> <p class="d-none d-md-block">(Reconeixement - No Comercial - Compartir Igual)</p> <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ca" target="_blank"> <img class="mx-auto" src="/itb/images/license.png" alt="Licence"/> </a> </div><!--license--> </div><!--cover--> </div><!--page--> {:toc} ## Introducció En el món de les bases de dades, organitzar i resumir les dades és un aspecte fonamental per extreure conclusions significatives. En aquest moment entra en joc la clàusula `GROUP BY`, que permet __agrupar i agregar__ dades basant-se en criteris específics. ## Funcions d'agrupació Alhora d'agrupar les dades es poden utilitzar les __funcions d'agregació__ per realitzar operacions i agregar les dades (Veure [Material: Consultes bàsiques - Funcions d'agragació](/itb/DAM-BD/UD5/materials/02_select.html#funcions-d'agregació)). Les funcions més comuns són: - `COUNT(A)`: Compta el nombre de registres de la columna `A`. - `MIN(A)`: Retorna el valor mínim dels registres de la columna `A`. - `MAX(A)`: Retorna el valor màxim dels registres de la columna `A`. - `SUM(A)`: Retorna la suma dels valors dels registres de la columna `A`. - `AVG(A)`: Retorna la mitjana aritmètica dels valors dels registres de la columna `A`. - `DISTINCT(A)`: Retorna els valors no repetits dels registres de la columna `A`. ## `GROUP BY` La clàusula `GROUP BY` pot ser utilitzada en sentències `SELECT` per agrupar les dades basant-se en un criteri concret. La sintàxi és: ```sql SELECT [ALL | DISTINCT | DISTINCTROW] column_expr [[AS] alias] [, column2_expr [[AS] alias2] ...] FROM table [WHERE condition] [ORDER BY {col_name} [ASC | DESC], ...] [GROUP BY {col_name} [ASC | DESC], ... [WITH ROLLUP]] [HAVING aggregate_condition] ``` - `GROUP BY`: Indica que es realitzarà una agrupació basant-se en les columnes definides. - `col_name, ...`: Indica quines columnes s'utilitzaran per realitar l'agrupació. Tots els registres que tinguen els mateixos valors en les columnes especificades s'agruparan en un únic registre. - `WITH ROLLUP`: Quan s'indica més d'uan columna, també s'obtindran els subtotals. - `HAVING aggregate_condition`: S'utilitza per definir condicions utilitzant les columnes agrupades, semblant al funcionament de `WHERE`. ::: docs Documentació oficial sobre agrupació: - MariaDB: https://mariadb.com/kb/en/group-by/ - MySQL 8.0: https://dev.mysql.com/doc/refman/8.0/en/aggregate-functions-and-modifiers.html ::: ### Agrupació amb una única columna Vegem com es poden agrupar registres d'una taula a partir d'una única columna. Tots els registres que tinguen el mateix valor en la columna indicada seran agrupats. ::: note "Dades d'exemple" En aquest apartat treballarem amb una versió simplidicada de la taula __cursa__ de la [base de dades Institut](/itb/DAM-BD/UD5/examples/01_dml_highschool.html). <table id="figure-3.1.3" class="center"> <caption>Figura 3.1.1: Taula <code>cursa</code> amb els seus registres</caption> <thead> <tr> <th style="text-align:center" colspan="3">Taula Cursa</th> </tr> <tr> <th style="text-align:center">ID Mòdul</th> <th style="text-align:center">NIA</th> <th style="text-align:center">Nota</th> </tr> </thead> <tbody> <!-- 0484 Bases de Dades --> <tr> <td style="text-align:center" class="">0484</td> <td style="text-align:center" class="">00000000</td> <td style="text-align:center" class="">5.6</td> </tr> <tr> <td style="text-align:center" class="">0484</td> <td style="text-align:center" class="">00000001</td> <td style="text-align:center" class="">8.0</td> </tr> <tr> <td style="text-align:center" class="">0484</td> <td style="text-align:center" class="">00000002</td> <td style="text-align:center" class="">4.3</td> </tr> <!-- 0485 Programació --> <tr> <td style="text-align:center" class="">0485</td> <td style="text-align:center" class="">00000000</td> <td style="text-align:center" class="">7.1</td> </tr> <tr> <td style="text-align:center" class="">0485</td> <td style="text-align:center" class="">00000001</td> <td style="text-align:center" class="">9.2</td> </tr> <tr> <td style="text-align:center" class="">0485</td> <td style="text-align:center" class="">00000002</td> <td style="text-align:center" class="">6.1</td> </tr> </tbody> </table> ```sql CREATE TABLE cursa ( id_modul varchar(6), nia varchar(8), nota decimal(4,2) check (nota >= 0 and nota <= 10), primary key (nia, id_modul) ); INSERT INTO cursa (id_modul, nia, nota) VALUES ("0484", "00000000", 5.6), ("0484", "00000001", 8.0), ("0484", "00000002", 4.3), ("0485", "00000000", 7.1), ("0485", "00000001", 9.2), ("0485", "00000002", 6.1); ``` ::: ::: example "Agrupació per estudiant" Mitjançant la clàusula `GROUP BY` agrupem els resultats de cada estudiant. Per fer-ho, cal indicar en aquesta clàusula la columna que serveix com a criteri per fer l'agrupació. En aquest cas, haurem d'utilitzar el `nia`. <table id="figure-3.1.2" class="center"> <caption>Figura 3.1.2: Registres agrupats mitjançant <code>GROUP BY</code> amb el camp <code>nia</code></caption> <thead> <tr> <th style="text-align:center" colspan="3">Taula Cursa</th> </tr> <tr> <th style="text-align:center">ID Mòdul</th> <th style="text-align:center">NIA</th> <th style="text-align:center">Nota</th> </tr> </thead> <tbody> <!-- 0484 Bases de Dades --> <tr> <td style="text-align:center" class="orange2">0484</td> <td style="text-align:center" class="orange2">00000000</td> <td style="text-align:center" class="orange2">5.6</td> </tr> <tr> <td style="text-align:center" class="blue2">0484</td> <td style="text-align:center" class="blue2">00000001</td> <td style="text-align:center" class="blue2">8.0</td> </tr> <tr> <td style="text-align:center" class="green2">0484</td> <td style="text-align:center" class="green2">00000002</td> <td style="text-align:center" class="green2">4.3</td> </tr> <!-- 0485 Programació --> <tr> <td style="text-align:center" class="orange2">0485</td> <td style="text-align:center" class="orange2">00000000</td> <td style="text-align:center" class="orange2">7.1</td> </tr> <tr> <td style="text-align:center" class="blue2">0485</td> <td style="text-align:center" class="blue2">00000001</td> <td style="text-align:center" class="blue2">9.2</td> </tr> <tr> <td style="text-align:center" class="green2">0485</td> <td style="text-align:center" class="green2">00000002</td> <td style="text-align:center" class="green2">6.1</td> </tr> </tbody> </table> Desitjem obtindre la nota mitjana obtinguda per cada estudiant en tots els mòduls que ha cursat. ```sql SELECT nia, avg(nota) nota_mitjana FROM cursa GROUP BY nia; +----------+--------------+ | nia | nota_mitjana | +----------+--------------+ | 00000000 | 6.350000 | | 00000001 | 8.600000 | | 00000002 | 5.200000 | +----------+--------------+ ``` ::: ::: example "Agrupació per mòdul" En aquest cas, agrupem les mateixes dades per obtindre la mitjana de les notes obtingudes pels estudiants per cada mòdul. L'agrupació s'haurà de realitzar amb la columna `id_modul` <table id="figure-3.1.3" class="center"> <caption>Figura 3.1.3: Registres agrupats mitjançant <code>GROUP BY</code> amb el camp <code>id_modul</code></caption> <thead> <tr> <th style="text-align:center" colspan="3">Taula Cursa</th> </tr> <tr> <th style="text-align:center">ID Mòdul</th> <th style="text-align:center">NIA</th> <th style="text-align:center">Nota</th> </tr> </thead> <tbody> <!-- 0484 Bases de Dades --> <tr> <td style="text-align:center" class="orange2">0484</td> <td style="text-align:center" class="orange2">00000000</td> <td style="text-align:center" class="orange2">5.6</td> </tr> <tr> <td style="text-align:center" class="orange2">0484</td> <td style="text-align:center" class="orange2">00000001</td> <td style="text-align:center" class="orange2">8.0</td> </tr> <tr> <td style="text-align:center" class="orange2">0484</td> <td style="text-align:center" class="orange2">00000002</td> <td style="text-align:center" class="orange2">4.3</td> </tr> <!-- 0485 Programació --> <tr> <td style="text-align:center" class="blue2">0485</td> <td style="text-align:center" class="blue2">00000000</td> <td style="text-align:center" class="blue2">7.1</td> </tr> <tr> <td style="text-align:center" class="blue2">0485</td> <td style="text-align:center" class="blue2">00000001</td> <td style="text-align:center" class="blue2">9.2</td> </tr> <tr> <td style="text-align:center" class="blue2">0485</td> <td style="text-align:center" class="blue2">00000002</td> <td style="text-align:center" class="blue2">6.1</td> </tr> </tbody> </table> ```sql SELECT id_modul, avg(nota) nota_mitjana FROM cursa GROUP BY id_modul; +----------+--------------+ | id_modul | nota_mitjana | +----------+--------------+ | 0484 | 5.966667 | | 0485 | 7.466667 | +----------+--------------+ ``` ::: ### Agrupació amb múltiples columnes Vegem com es poden agrupar registres d'una taula a partir de múltiples columnes. Tots els registres que tinguen el mateixos valors en la columnes indicades seran agrupats. ::: note "Dades d'exemple" Afegim la columna `curs_academic` a la taula `cursa`. <table id="figure-3.2.1" class="center"> <caption>Figura 3.2.1: Taula <code>cursa</code> amb el curs acadèmic i els seus registres</caption> <thead> <tr> <th style="text-align:center" colspan="4">Taula Cursa</th> </tr> <tr> <th style="text-align:center">ID Mòdul</th> <th style="text-align:center">NIA</th> <th style="text-align:center">Nota</th> <th style="text-align:center">Curs acadèmic</th> </tr> </thead> <tbody> <!-- 0484 Bases de Dades --> <tr> <td style="text-align:center" class="">0484</td> <td style="text-align:center" class="">00000000</td> <td style="text-align:center" class="">5.6</td> <td style="text-align:center" class="">23/24</td> </tr> <tr> <td style="text-align:center" class="">0484</td> <td style="text-align:center" class="">00000001</td> <td style="text-align:center" class="">8.0</td> <td style="text-align:center" class="">23/24</td> </tr> <tr> <td style="text-align:center" class="">0484</td> <td style="text-align:center" class="">00000002</td> <td style="text-align:center" class="">4.3</td> <td style="text-align:center" class="">23/24</td> </tr> <!-- 0485 Programació --> <tr> <td style="text-align:center" class="">0485</td> <td style="text-align:center" class="">00000000</td> <td style="text-align:center" class="">7.1</td> <td style="text-align:center" class="">23/24</td> </tr> <tr> <td style="text-align:center" class="">0485</td> <td style="text-align:center" class="">00000001</td> <td style="text-align:center" class="">9.2</td> <td style="text-align:center" class="">23/24</td> </tr> <tr> <td style="text-align:center" class="">0485</td> <td style="text-align:center" class="">00000002</td> <td style="text-align:center" class="">6.1</td> <td style="text-align:center" class="">23/24</td> </tr> <!-- Estudiants de segon --> <tr> <td style="text-align:center" class="">0484</td> <td style="text-align:center" class="">00000003</td> <td style="text-align:center" class="">6.3</td> <td style="text-align:center" class="">22/23</td> </tr> <tr> <td style="text-align:center" class="">0484</td> <td style="text-align:center" class="">00000004</td> <td style="text-align:center" class="">9.5</td> <td style="text-align:center" class="">22/23</td> </tr> <tr> <td style="text-align:center" class="">0485</td> <td style="text-align:center" class="">00000003</td> <td style="text-align:center" class="">7.8</td> <td style="text-align:center" class="">22/23</td> </tr> <tr> <td style="text-align:center" class="">0485</td> <td style="text-align:center" class="">00000004</td> <td style="text-align:center" class="">8.3</td> <td style="text-align:center" class="">22/23</td> </tr> <tr> <td style="text-align:center" class="">0489</td> <td style="text-align:center" class="">00000003</td> <td style="text-align:center" class="">7.2</td> <td style="text-align:center" class="">23/24</td> </tr> <tr> <td style="text-align:center" class="">0489</td> <td style="text-align:center" class="">00000004</td> <td style="text-align:center" class="">6.8</td> <td style="text-align:center" class="">23/24</td> </tr> <tr> <td style="text-align:center" class="">0490</td> <td style="text-align:center" class="">00000003</td> <td style="text-align:center" class="">8.9</td> <td style="text-align:center" class="">23/24</td> </tr> <tr> <td style="text-align:center" class="">0490</td> <td style="text-align:center" class="">00000004</td> <td style="text-align:center" class="">8.1</td> <td style="text-align:center" class="">23/24</td> </tr> </tbody> </table> ```sql CREATE TABLE cursa ( id_modul varchar(6), nia varchar(8), nota decimal(4,2) check (nota >= 0 and nota <= 10), curs_academic char(5), primary key (nia, id_modul, curs_academic) ); INSERT INTO cursa (id_modul, nia, nota, curs_academic) VALUES ("0484", "00000000", 5.6, "23/24"), ("0484", "00000001", 8.0, "23/24"), ("0484", "00000002", 4.3, "23/24"), ("0485", "00000000", 7.1, "23/24"), ("0485", "00000001", 9.2, "23/24"), ("0485", "00000002", 6.1, "23/24"), ("0484", "00000003", 6.3, "22/23"), ("0484", "00000004", 9.5, "22/23"), ("0485", "00000003", 7.8, "22/23"), ("0485", "00000004", 8.3, "22/23"), ("0489", "00000003", 7.2, "23/24"), ("0489", "00000004", 6.8, "23/24"), ("0490", "00000003", 8.9, "23/24"), ("0490", "00000004", 8.1, "23/24"); ``` ::: ::: example "Agrupació per mòdul i curs acadèmic" Amb les dades anteriors, si sols agrupem els registres per mòdul professional, el càlcul de la nota mitjana es realitzaria amb les notes de tots els estudiants de tots els cursos acadèmics. Si volem veure la nota mitjana de cada mòdul en cada curs acadèmic, hem d'indicar els dos camps en la clàusula `GROUP BY`. <table id="figure-3.2.2" class="center"> <caption>Figura 3.2.2: Registres agrupats pels camps <code>id_modul</code> i <code>curs_academic</code></caption> <thead> <tr> <th style="text-align:center" colspan="4">Taula Cursa</th> </tr> <tr> <th style="text-align:center">ID Mòdul</th> <th style="text-align:center">NIA</th> <th style="text-align:center">Nota</th> <th style="text-align:center">Curs acadèmic</th> </tr> </thead> <tbody> <!-- 0484 Bases de Dades --> <tr> <td style="text-align:center" class="orange2">0484</td> <td style="text-align:center" class="orange2">00000000</td> <td style="text-align:center" class="orange2">5.6</td> <td style="text-align:center" class="orange2">23/24</td> </tr> <tr> <td style="text-align:center" class="orange2">0484</td> <td style="text-align:center" class="orange2">00000001</td> <td style="text-align:center" class="orange2">8.0</td> <td style="text-align:center" class="orange2">23/24</td> </tr> <tr> <td style="text-align:center" class="orange2">0484</td> <td style="text-align:center" class="orange2">00000002</td> <td style="text-align:center" class="orange2">4.3</td> <td style="text-align:center" class="orange2">23/24</td> </tr> <!-- 0485 Programació --> <tr> <td style="text-align:center" class="blue2">0485</td> <td style="text-align:center" class="blue2">00000000</td> <td style="text-align:center" class="blue2">7.1</td> <td style="text-align:center" class="blue2">23/24</td> </tr> <tr> <td style="text-align:center" class="blue2">0485</td> <td style="text-align:center" class="blue2">00000001</td> <td style="text-align:center" class="blue2">9.2</td> <td style="text-align:center" class="blue2">23/24</td> </tr> <tr> <td style="text-align:center" class="blue2">0485</td> <td style="text-align:center" class="blue2">00000002</td> <td style="text-align:center" class="blue2">6.1</td> <td style="text-align:center" class="blue2">23/24</td> </tr> <!-- Estudiants de segon --> <tr> <td style="text-align:center" class="green2">0484</td> <td style="text-align:center" class="green2">00000003</td> <td style="text-align:center" class="green2">6.3</td> <td style="text-align:center" class="green2">22/23</td> </tr> <tr> <td style="text-align:center" class="green2">0484</td> <td style="text-align:center" class="green2">00000004</td> <td style="text-align:center" class="green2">9.5</td> <td style="text-align:center" class="green2">22/23</td> </tr> <tr> <td style="text-align:center" class="purple2">0485</td> <td style="text-align:center" class="purple2">00000003</td> <td style="text-align:center" class="purple2">7.8</td> <td style="text-align:center" class="purple2">22/23</td> </tr> <tr> <td style="text-align:center" class="purple2">0485</td> <td style="text-align:center" class="purple2">00000004</td> <td style="text-align:center" class="purple2">8.3</td> <td style="text-align:center" class="purple2">22/23</td> </tr> <tr> <td style="text-align:center" class="red2">0489</td> <td style="text-align:center" class="red2">00000003</td> <td style="text-align:center" class="red2">7.2</td> <td style="text-align:center" class="red2">23/24</td> </tr> <tr> <td style="text-align:center" class="red2">0489</td> <td style="text-align:center" class="red2">00000004</td> <td style="text-align:center" class="red2">6.8</td> <td style="text-align:center" class="red2">23/24</td> </tr> <tr> <td style="text-align:center" class="teal2">0490</td> <td style="text-align:center" class="teal2">00000003</td> <td style="text-align:center" class="teal2">8.9</td> <td style="text-align:center" class="teal2">23/24</td> </tr> <tr> <td style="text-align:center" class="teal2">0490</td> <td style="text-align:center" class="teal2">00000004</td> <td style="text-align:center" class="teal2">8.1</td> <td style="text-align:center" class="teal2">23/24</td> </tr> </tbody> </table> ```sql SELECT id_modul, curs_academic, avg(nota) nota_mitjana FROM cursa GROUP BY id_modul, curs_academic ORDER BY id_modul, curs_academic; +----------+---------------+---------------+ | id_modul | curs_academic | nota_mitajana | +----------+---------------+---------------+ | 0484 | 22/23 | 7.900000 | | 0484 | 23/24 | 5.966667 | | 0485 | 22/23 | 8.050000 | | 0485 | 23/24 | 7.466667 | | 0489 | 23/24 | 7.000000 | | 0490 | 23/24 | 8.500000 | +----------+---------------+---------------+ ``` ::: ::: example "Agrupació per estudiant i curs acadèmic" De la mateixa manera, podem agrupar les notes dels estudiants per cada curs acadèmic. <table id="figure-3.2.3" class="center"> <caption>Figura 3.2.3: Registres agrupats pels camps <code>nia</code> i <code>curs_academic</code></caption> <thead> <tr> <th style="text-align:center" colspan="4">Taula Cursa</th> </tr> <tr> <th style="text-align:center">ID Mòdul</th> <th style="text-align:center">NIA</th> <th style="text-align:center">Nota</th> <th style="text-align:center">Curs acadèmic</th> </tr> </thead> <tbody> <!-- 0484 Bases de Dades --> <tr> <td style="text-align:center" class="orange2">0484</td> <td style="text-align:center" class="orange2">00000000</td> <td style="text-align:center" class="orange2">5.6</td> <td style="text-align:center" class="orange2">23/24</td> </tr> <tr> <td style="text-align:center" class="blue2">0484</td> <td style="text-align:center" class="blue2">00000001</td> <td style="text-align:center" class="blue2">8.0</td> <td style="text-align:center" class="blue2">23/24</td> </tr> <tr> <td style="text-align:center" class="green2">0484</td> <td style="text-align:center" class="green2">00000002</td> <td style="text-align:center" class="green2">4.3</td> <td style="text-align:center" class="green2">23/24</td> </tr> <!-- 0485 Programació --> <tr> <td style="text-align:center" class="orange2">0485</td> <td style="text-align:center" class="orange2">00000000</td> <td style="text-align:center" class="orange2">7.1</td> <td style="text-align:center" class="orange2">23/24</td> </tr> <tr> <td style="text-align:center" class="blue2">0485</td> <td style="text-align:center" class="blue2">00000001</td> <td style="text-align:center" class="blue2">9.2</td> <td style="text-align:center" class="blue2">23/24</td> </tr> <tr> <td style="text-align:center" class="green2">0485</td> <td style="text-align:center" class="green2">00000002</td> <td style="text-align:center" class="green2">6.1</td> <td style="text-align:center" class="green2">23/24</td> </tr> <!-- Estudiants de segon --> <tr> <td style="text-align:center" class="purple2">0484</td> <td style="text-align:center" class="purple2">00000003</td> <td style="text-align:center" class="purple2">6.3</td> <td style="text-align:center" class="purple2">22/23</td> </tr> <tr> <td style="text-align:center" class="red2">0484</td> <td style="text-align:center" class="red2">00000004</td> <td style="text-align:center" class="red2">9.5</td> <td style="text-align:center" class="red2">22/23</td> </tr> <tr> <td style="text-align:center" class="purple2">0485</td> <td style="text-align:center" class="purple2">00000003</td> <td style="text-align:center" class="purple2">7.8</td> <td style="text-align:center" class="purple2">22/23</td> </tr> <tr> <td style="text-align:center" class="red2">0485</td> <td style="text-align:center" class="red2">00000004</td> <td style="text-align:center" class="red2">8.3</td> <td style="text-align:center" class="red2">22/23</td> </tr> <tr> <td style="text-align:center" class="teal2">0489</td> <td style="text-align:center" class="teal2">00000003</td> <td style="text-align:center" class="teal2">7.2</td> <td style="text-align:center" class="teal2">23/24</td> </tr> <tr> <td style="text-align:center" class="aquamarine2">0489</td> <td style="text-align:center" class="aquamarine2">00000004</td> <td style="text-align:center" class="aquamarine2">6.8</td> <td style="text-align:center" class="aquamarine2">23/24</td> </tr> <tr> <td style="text-align:center" class="teal2">0490</td> <td style="text-align:center" class="teal2">00000003</td> <td style="text-align:center" class="teal2">8.9</td> <td style="text-align:center" class="teal2">23/24</td> </tr> <tr> <td style="text-align:center" class="aquamarine2">0490</td> <td style="text-align:center" class="aquamarine2">00000004</td> <td style="text-align:center" class="aquamarine2">8.1</td> <td style="text-align:center" class="aquamarine2">23/24</td> </tr> </tbody> </table> ```sql SELECT nia, curs_academic, avg(nota) nota_mitjana FROM cursa GROUP BY nia, curs_academic ORDER BY nia, curs_academic; +----------+---------------+--------------+ | nia | curs_academic | nota_mitjana | +----------+---------------+--------------+ | 00000000 | 23/24 | 6.350000 | | 00000001 | 23/24 | 8.600000 | | 00000002 | 23/24 | 5.200000 | | 00000003 | 22/23 | 7.050000 | | 00000003 | 23/24 | 8.050000 | | 00000004 | 22/23 | 8.900000 | | 00000004 | 23/24 | 7.450000 | +----------+---------------+--------------+ ``` ::: ### Agrupació amb subtotals (`ROLLUP`) Les paraules claus `WITH ROLLUP` en la clàusula `GROUP BY` serveixen per, a més de mostrar els resultats de l'agrupament, també mostrar els subtotals que existeixen. En el resultats, els subtotals calculats tindran el valor `NULL` en alguna de les columnes utilitzades en l'agrupació, per indicar que aquest camp no s'ha tingut en compte al realitzar el càlcul del subtotal. ::: example "Agrupació per mòdul i curs acadèmic amb subtotals" Agrupem els registres de cada mòdul per cada curs acadèmic. En aquest cas, els subtotals calculats són: - La mitjana de totes les notes. - La mitjana de les notes de cada mòdul en tots els cursos acadèmics. ```sql SELECT id_modul, curs_academic, avg(nota) nota_mitjana FROM cursa GROUP BY id_modul, curs_academic WITH ROLLUP ORDER BY id_modul, curs_academic; +----------+---------------+--------------+ | id_modul | curs_academic | nota_mitjana | +----------+---------------+--------------+ | NULL | NULL | 7.371429 | | 0484 | NULL | 6.740000 | | 0484 | 22/23 | 7.900000 | | 0484 | 23/24 | 5.966667 | | 0485 | NULL | 7.700000 | | 0485 | 22/23 | 8.050000 | | 0485 | 23/24 | 7.466667 | | 0489 | NULL | 7.000000 | | 0489 | 23/24 | 7.000000 | | 0490 | NULL | 8.500000 | | 0490 | 23/24 | 8.500000 | +----------+---------------+--------------+ ``` ::: ::: example "Agrupació per mòdul i curs acadèmic amb subtotals" Agrupem els registres de cada estudiant per cada curs acadèmic. En aquest cas, els subtotals calculats són: - La mitjana de totes les notes. - La mitjana de les notes de cada estudiant en tots els cursos acadèmics. ```sql SELECT nia, curs_academic, avg(nota) nota_mitjana FROM cursa GROUP BY nia, curs_academic WITH ROLLUP ORDER BY nia, curs_academic; +----------+---------------+--------------+ | nia | curs_academic | nota_mitjana | +----------+---------------+--------------+ | NULL | NULL | 7.371429 | | 00000000 | NULL | 6.350000 | | 00000000 | 23/24 | 6.350000 | | 00000001 | NULL | 8.600000 | | 00000001 | 23/24 | 8.600000 | | 00000002 | NULL | 5.200000 | | 00000002 | 23/24 | 5.200000 | | 00000003 | NULL | 7.550000 | | 00000003 | 22/23 | 7.050000 | | 00000003 | 23/24 | 8.050000 | | 00000004 | NULL | 8.175000 | | 00000004 | 22/23 | 8.900000 | | 00000004 | 23/24 | 7.450000 | +----------+---------------+--------------+ ``` ::: ## `HAVING` La clàusula `HAVING` serveix per filtrar es resultats d'una consulta que utilitza `GROUP BY` a partir d'una condició. La diferència amb la clàusula `WHERE` és que `HAVING` s'aplica després de fer l'agrupació i `WHERE` s'aplica abans. ::: example "Agrupació per estudiant i curs acadèmic amb una condició" De la mateixa manera, podem agrupar les notes dels estudiants per cada curs acadèmic. ```sql SELECT nia, curs_academic, avg(nota) nota_mitjana FROM cursa GROUP BY nia, curs_academic HAVING nota_mitjana >= 8 ORDER BY nia, curs_academic; +----------+---------------+--------------+ | nia | curs_academic | nota_mitjana | +----------+---------------+--------------+ | 00000001 | 23/24 | 8.600000 | | 00000003 | 23/24 | 8.050000 | | 00000004 | 22/23 | 8.900000 | +----------+---------------+--------------+ ``` :::