<div class="page">
<div class="cover text-center">
<img class="mx-auto" src=/itb/images/logo_mislata.png alt="logo">
# Consultes amb múltiples taules
<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ó
Fins ara hem realitzat consultes `SELECT` a partir una única taula (`FROM`).
No obstant això, les bases de dades relacionals estan pensades per relacionar les dades de múltiples taules,
navegant les claus foranes i combinant la informació per extraure dades que complixen condicions més complexes.
Hi ha diferents maneres de combinar múltiples taules, però la més elegant és mitjançant la clàusula `JOIN`.
::: docs
Documentació oficial sobre `JOIN`:
- MariaDB: https://mariadb.com/kb/en/joins/
- MySQL 8.0: https://dev.mysql.com/doc/refman/8.0/en/join.html
:::
## Taules i dades d'exemple
Tots els exemples es realitzaran amb les següents taules i dades:
```sql
CREATE DATABASE tenda;
USE tenda;
CREATE TABLE categoria (
id_categoria INT PRIMARY KEY AUTO_INCREMENT,
nom VARCHAR(50) NOT NULL
);
CREATE TABLE producte (
id_producte INT PRIMARY KEY AUTO_INCREMENT,
id_categoria INT,
nom VARCHAR(50) NOT NULL,
preu DECIMAL(5,2) NOT NULL,
FOREIGN KEY (id_categoria) REFERENCES categoria (id_categoria)
);
INSERT INTO categoria (id_categoria, nom) VALUES
(1, "Forn"),
(2, "Beguda"),
(3, "Higiene"),
(4, "Fruta");
INSERT INTO producte (id_producte, id_categoria, nom, preu) VALUES
(1, 1, "Barra de pà", 0.7),
(2, 1, "Pastís de xocolate", 5.3),
(3, 2, "Botella d'aigua 50cL", 0.8),
(4, NULL, "Piles AA", 1.5),
(5, 4, "Pera", 0.3),
(6, 4, "Plàtan", 0.5);
```
<div class="d-flex justify-content-evenly flex-wrap">
<table>
<caption>Figura 2.1: Taula Catgoria amb les seues dades</caption>
<thead>
<tr>
<th style="text-align:center" colspan="2">Taula Categoria</th>
</tr>
<tr>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
</tr>
</thead>
<tbody>
<tr class="orange1">
<td style="text-align:center">1</td>
<td style="text-align:center">Forn </td>
</tr>
<tr class="orange2">
<td style="text-align:center">2</td>
<td style="text-align:center">Beguda </td>
</tr>
<tr class="orange3">
<td style="text-align:center">3</td>
<td style="text-align:center">Higiene</td>
</tr>
<tr class="orange4">
<td style="text-align:center">4</td>
<td style="text-align:center">Fruta </td>
</tr>
</tbody>
</table>
<table>
<caption>Figura 2.2: Taula Producte amb les seues dades</caption>
<thead>
<tr>
<th style="text-align:center" colspan="4">Taula Producte</th>
</tr>
<tr>
<th style="text-align:center">ID Producte</th>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
<th style="text-align:center">Preu</th>
</tr>
</thead>
<tbody>
<tr class="blue1">
<td style="text-align:center">1</td>
<td style="text-align:center">1</td>
<td style="text-align:center">Barra de pà</td>
<td style="text-align:center">0.70</td>
</tr>
<tr class="blue2">
<td style="text-align:center">2</td>
<td style="text-align:center">1</td>
<td style="text-align:center">Pastís de xocolate</td>
<td style="text-align:center">5.30</td>
</tr>
<tr class="blue3">
<td style="text-align:center">3</td>
<td style="text-align:center">2</td>
<td style="text-align:center">Botella d'aigua 50cL</td>
<td style="text-align:center">0.80</td>
</tr>
<tr class="blue4">
<td style="text-align:center">4</td>
<td style="text-align:center">NULL</td>
<td style="text-align:center">Piles AA</td>
<td style="text-align:center">1.50</td>
</tr>
<tr class="blue5">
<td style="text-align:center">5</td>
<td style="text-align:center">4</td>
<td style="text-align:center">Pera</td>
<td style="text-align:center">0.30</td>
</tr>
<tr class="blue6">
<td style="text-align:center">6</td>
<td style="text-align:center">4</td>
<td style="text-align:center">Plàtan</td>
<td style="text-align:center">0.50</td>
</tr>
</tbody>
</table>
</div>
## Producte cartesià o `CROSS JOIN`
Sempre que es desitge combinar múltiples taules, el SGBD realitzarà
el __producte cartesià__ entre les taules, que després filtrarà
per obtindre el resultat esperat.
#3.1[Producte cartesià entre dos conjunts](/itb/DAM-BD/UD5/img/joins/cross_join.svg)
El producte cartesià retorna
una taula on cada element d'una taula estarà combinat amb cadascun
dels elements de l'altra taula.
::: example
<table id="figure-3.2" class="center">
<caption>Figura 3.2: Resultat del producte cartesià entre les taules Producte i Categoria</caption>
<thead>
<tr>
<th style="text-align:center" colspan="2">Taula Categoria</th>
<th style="text-align:center" colspan="4">Taula Producte</th>
</tr>
<tr>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
<th style="text-align:center">ID Producte</th>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
<th style="text-align:center">Preu</th>
</tr>
</thead>
<tbody>
<!-- 1 Forn -->
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">Barra de pà</td>
<td style="text-align:center" class="blue1">0.70</td>
</tr>
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue2">2</td>
<td style="text-align:center" class="blue2">1</td>
<td style="text-align:center" class="blue2">Pastís de xocolate</td>
<td style="text-align:center" class="blue2">5.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue3">3</td>
<td style="text-align:center" class="blue3">2</td>
<td style="text-align:center" class="blue3">Botella d'aigua 50cL</td>
<td style="text-align:center" class="blue3">0.80</td>
</tr>
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue4">4</td>
<td style="text-align:center" class="blue4">NULL</td>
<td style="text-align:center" class="blue4">Piles AA</td>
<td style="text-align:center" class="blue4">1.50</td>
</tr>
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue5">5</td>
<td style="text-align:center" class="blue5">4</td>
<td style="text-align:center" class="blue5">Pera</td>
<td style="text-align:center" class="blue5">0.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue6">6</td>
<td style="text-align:center" class="blue6">4</td>
<td style="text-align:center" class="blue6">Plàtan</td>
<td style="text-align:center" class="blue6">0.50</td>
<!-- 2 Beguda -->
<tr>
<td style="text-align:center" class="orange2">2</td>
<td style="text-align:center" class="orange2">Beguda</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">Barra de pà</td>
<td style="text-align:center" class="blue1">0.70</td>
</tr>
<tr>
<td style="text-align:center" class="orange2">2</td>
<td style="text-align:center" class="orange2">Beguda</td>
<td style="text-align:center" class="blue2">2</td>
<td style="text-align:center" class="blue2">1</td>
<td style="text-align:center" class="blue2">Pastís de xocolate</td>
<td style="text-align:center" class="blue2">5.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange2">2</td>
<td style="text-align:center" class="orange2">Beguda</td>
<td style="text-align:center" class="blue3">3</td>
<td style="text-align:center" class="blue3">2</td>
<td style="text-align:center" class="blue3">Botella d'aigua 50cL</td>
<td style="text-align:center" class="blue3">0.80</td>
</tr>
<tr>
<td style="text-align:center" class="orange2">2</td>
<td style="text-align:center" class="orange2">Beguda</td>
<td style="text-align:center" class="blue4">4</td>
<td style="text-align:center" class="blue4">NULL</td>
<td style="text-align:center" class="blue4">Piles AA</td>
<td style="text-align:center" class="blue4">1.50</td>
</tr>
<tr>
<td style="text-align:center" class="orange2">2</td>
<td style="text-align:center" class="orange2">Beguda</td>
<td style="text-align:center" class="blue5">5</td>
<td style="text-align:center" class="blue5">4</td>
<td style="text-align:center" class="blue5">Pera</td>
<td style="text-align:center" class="blue5">0.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange2">2</td>
<td style="text-align:center" class="orange2">Beguda</td>
<td style="text-align:center" class="blue6">6</td>
<td style="text-align:center" class="blue6">4</td>
<td style="text-align:center" class="blue6">Plàtan</td>
<td style="text-align:center" class="blue6">0.50</td>
<!-- 3 Higiene -->
<tr>
<td style="text-align:center" class="orange3">3</td>
<td style="text-align:center" class="orange3">Higiene</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">Barra de pà</td>
<td style="text-align:center" class="blue1">0.70</td>
</tr>
<tr>
<td style="text-align:center" class="orange3">3</td>
<td style="text-align:center" class="orange3">Higiene</td>
<td style="text-align:center" class="blue2">2</td>
<td style="text-align:center" class="blue2">1</td>
<td style="text-align:center" class="blue2">Pastís de xocolate</td>
<td style="text-align:center" class="blue2">5.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange3">3</td>
<td style="text-align:center" class="orange3">Higiene</td>
<td style="text-align:center" class="blue3">3</td>
<td style="text-align:center" class="blue3">2</td>
<td style="text-align:center" class="blue3">Botella d'aigua 50cL</td>
<td style="text-align:center" class="blue3">0.80</td>
</tr>
<tr>
<td style="text-align:center" class="orange3">3</td>
<td style="text-align:center" class="orange3">Higiene</td>
<td style="text-align:center" class="blue4">4</td>
<td style="text-align:center" class="blue4">NULL</td>
<td style="text-align:center" class="blue4">Piles AA</td>
<td style="text-align:center" class="blue4">1.50</td>
</tr>
<tr>
<td style="text-align:center" class="orange3">3</td>
<td style="text-align:center" class="orange3">Higiene</td>
<td style="text-align:center" class="blue5">5</td>
<td style="text-align:center" class="blue5">4</td>
<td style="text-align:center" class="blue5">Pera</td>
<td style="text-align:center" class="blue5">0.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange3">3</td>
<td style="text-align:center" class="orange3">Higiene</td>
<td style="text-align:center" class="blue6">6</td>
<td style="text-align:center" class="blue6">4</td>
<td style="text-align:center" class="blue6">Plàtan</td>
<td style="text-align:center" class="blue6">0.50</td>
<!-- 4 Fruta -->
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">Barra de pà</td>
<td style="text-align:center" class="blue1">0.70</td>
</tr>
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue2">2</td>
<td style="text-align:center" class="blue2">1</td>
<td style="text-align:center" class="blue2">Pastís de xocolate</td>
<td style="text-align:center" class="blue2">5.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue3">3</td>
<td style="text-align:center" class="blue3">2</td>
<td style="text-align:center" class="blue3">Botella d'aigua 50cL</td>
<td style="text-align:center" class="blue3">0.80</td>
</tr>
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue4">4</td>
<td style="text-align:center" class="blue4">NULL</td>
<td style="text-align:center" class="blue4">Piles AA</td>
<td style="text-align:center" class="blue4">1.50</td>
</tr>
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue5">5</td>
<td style="text-align:center" class="blue5">4</td>
<td style="text-align:center" class="blue5">Pera</td>
<td style="text-align:center" class="blue5">0.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue6">6</td>
<td style="text-align:center" class="blue6">4</td>
<td style="text-align:center" class="blue6">Plàtan</td>
<td style="text-align:center" class="blue6">0.50</td>
</tr>
</tbody>
</table>
:::
El SGBD retornarà el producte cartesià entre dues taules si:
- Realitzem un `JOIN` o `CROSS JOIN` sense cap condició.
::: example
```sql
SELECT * FROM categoria
CROSS JOIN producte;
```
:::
- Realitzem una consulta amb múltiples taules en la clàusula `FROM`.
::: example
```sql
SELECT * FROM categoria, producte;
```
:::
## Combinació interna o `INNER JOIN`
El producte cartesià ens retorna totes les possibles combinacions entre diferents taules i
molts dels resultats no estan relacionats entre sí. Per filtrar els resultats i retornar
sols aquells registres que sí que estan relacionats entre si, cal utilitzar `INNER JOIN`,
que permet especificar una condició per especificar com es relacionen els registres
de les diferents taules. Normalment aquesta condició utilitza les claus foranes definides.
#4.1[Intersecció entre dos conjunts](/itb/DAM-BD/UD5/img/joins/inner_join.svg)
La clàusula `INNER JOIN` té la següent sintaxi:
```sql
SELECT columns
FROM table1 t1
INNER JOIN table2 t2
ON t1.attr = t2.attr
```
- `INNER JOIN`: Especifica la taula que es dessitja combinar. Es pot especificar un àlies.
- `ON`: Especifica els atributs que formen la relació entre les dues taules. Especifica la condició de filtratge.
::: info
Es poden definir àlies en les taules per poder referenciar les taules d'una manerà més fàcil i còmoda.
:::
::: example
La intersecció entre les taules Categoria i Producte ens retorna els productes relacionats amb les
categories als quals pertanyen.
<table id="figure-4.2" class="center">
<caption>Figura 4.2: Resultat del <code>INNER JOIN</code> entre les taules Producte i Categoria</caption>
<thead>
<tr>
<th style="text-align:center" colspan="2">Taula Categoria</th>
<th style="text-align:center" colspan="4">Taula Producte</th>
</tr>
<tr>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
<th style="text-align:center">ID Producte</th>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
<th style="text-align:center">Preu</th>
</tr>
</thead>
<tbody>
<!-- 1 Forn -->
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">Barra de pà</td>
<td style="text-align:center" class="blue1">0.70</td>
</tr>
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue2">2</td>
<td style="text-align:center" class="blue2">1</td>
<td style="text-align:center" class="blue2">Pastís de xocolate</td>
<td style="text-align:center" class="blue2">5.30</td>
</tr>
<!-- 2 Beguda -->
<tr>
<td style="text-align:center" class="orange2">2</td>
<td style="text-align:center" class="orange2">Beguda</td>
<td style="text-align:center" class="blue3">3</td>
<td style="text-align:center" class="blue3">2</td>
<td style="text-align:center" class="blue3">Botella d'aigua 50cL</td>
<td style="text-align:center" class="blue3">0.80</td>
</tr>
<!-- 4 Fruta -->
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue5">5</td>
<td style="text-align:center" class="blue5">4</td>
<td style="text-align:center" class="blue5">Pera</td>
<td style="text-align:center" class="blue5">0.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue6">6</td>
<td style="text-align:center" class="blue6">4</td>
<td style="text-align:center" class="blue6">Plàtan</td>
<td style="text-align:center" class="blue6">0.50</td>
</tr>
</tbody>
</table>
Aquest resultat es pot obtindre mitjançant la consulta:
```sql
SELECT c.id_categoria, c.nom, p.id_producte, p.id_categoria, p.nom, p.preu
FROM categoria c
INNER JOIN producte p
ON p.id_categoria = c.id_categoria;
```
S'ha especificat en la condició `ON` que relacione la taula Producte amb la taula Categoria mitjançant la clau forana
`id_categoria`.
:::
## Combinació externa: `LEFT JOIN`
La combinació externa `LEFT JOIN` retorna aquells registres que estan relacionats en les dues taules (`INNER JOIN`), però
també retorna els valors de la primera taula que no estan relacionats amb elements de la segona taula.
#5.1[LEFT JOIN entre dos conjunts](/itb/DAM-BD/UD5/img/joins/left_join.svg)
La clàusula `LEFT JOIN` té una sintaxi equivalent a `INNER JOIN`:
```sql
SELECT columns
FROM table1 t1
LEFT JOIN table2 t2
ON t1.attr = t2.attr
```
::: example
El `LEFT JOIN` entre les taules Categoria i Producte ens retorna les categories relacionades amb els
productes que tenen, però també aquelles categories que no tenen cap producte.
<table id="figure-5.2" class="center">
<caption>Figura 5.2: Resultat del LEFT JOIN entre les taules Producte i Categoria</caption>
<thead>
<tr>
<th style="text-align:center" colspan="2">Taula Categoria</th>
<th style="text-align:center" colspan="4">Taula Producte</th>
</tr>
<tr>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
<th style="text-align:center">ID Producte</th>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
<th style="text-align:center">Preu</th>
</tr>
</thead>
<tbody>
<!-- 1 Forn -->
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">Barra de pà</td>
<td style="text-align:center" class="blue1">0.70</td>
</tr>
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue2">2</td>
<td style="text-align:center" class="blue2">1</td>
<td style="text-align:center" class="blue2">Pastís de xocolate</td>
<td style="text-align:center" class="blue2">5.30</td>
</tr>
<!-- 2 Beguda -->
<tr>
<td style="text-align:center" class="orange2">2</td>
<td style="text-align:center" class="orange2">Beguda</td>
<td style="text-align:center" class="blue3">3</td>
<td style="text-align:center" class="blue3">2</td>
<td style="text-align:center" class="blue3">Botella d'aigua 50cL</td>
<td style="text-align:center" class="blue3">0.80</td>
</tr>
<!-- 3 Higiene -->
<tr>
<td style="text-align:center" class="orange3">3</td>
<td style="text-align:center" class="orange3">Higiene</td>
<td style="text-align:center" class="">NULL</td>
<td style="text-align:center" class="">NULL</td>
<td style="text-align:center" class="">NULL</td>
<td style="text-align:center" class="">NULL</td>
</tr>
<!-- 4 Fruta -->
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue5">5</td>
<td style="text-align:center" class="blue5">4</td>
<td style="text-align:center" class="blue5">Pera</td>
<td style="text-align:center" class="blue5">0.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue6">6</td>
<td style="text-align:center" class="blue6">4</td>
<td style="text-align:center" class="blue6">Plàtan</td>
<td style="text-align:center" class="blue6">0.50</td>
</tr>
</tbody>
</table>
Aquest resultat es pot obtindre mitjançant la consulta:
```sql
SELECT c.id_categoria, c.nom, p.id_producte, p.id_categoria, p.nom, p.preu
FROM categoria c
LEFT JOIN producte p
ON p.id_categoria = c.id_categoria;
```
:::
## Combinació externa: `RIGHT JOIN`
La combinació externa `RIGHT JOIN` retorna aquells registres que estan relacionats en les dues taules (`INNER JOIN`),
però també retorna els valors de la segona taula que no estan relacionats amb elements de la primera taula.
És exactament el mateix que un `LEFT JOIN` però en el altre sentit.
#6.1[RIGHT JOIN entre dos conjunts](/itb/DAM-BD/UD5/img/joins/right_join.svg)
La clàusula `RIGHT JOIN` té una sintaxi equivalent a `INNER JOIN`:
```sql
SELECT columns
FROM table1 t1
RIGHT JOIN table2 t2
ON t1.attr = t2.attr
```
::: example
El `RIGHT JOIN` entre les taules Categoria i Producte ens retorna les categories relacionades amb els
productes que tenen, però també aquells productes que no tenen cap categoria.
<table id="figure-6.2" class="center">
<caption>Figura 6.2: Resultat del RIGHT JOIN entre les taules Producte i Categoria</caption>
<thead>
<tr>
<th style="text-align:center" colspan="2">Taula Categoria</th>
<th style="text-align:center" colspan="4">Taula Producte</th>
</tr>
<tr>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
<th style="text-align:center">ID Producte</th>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
<th style="text-align:center">Preu</th>
</tr>
</thead>
<tbody>
<!-- 1 Forn -->
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">Barra de pà</td>
<td style="text-align:center" class="blue1">0.70</td>
</tr>
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue2">2</td>
<td style="text-align:center" class="blue2">1</td>
<td style="text-align:center" class="blue2">Pastís de xocolate</td>
<td style="text-align:center" class="blue2">5.30</td>
</tr>
<!-- 2 Beguda -->
<tr>
<td style="text-align:center" class="orange2">2</td>
<td style="text-align:center" class="orange2">Beguda</td>
<td style="text-align:center" class="blue3">3</td>
<td style="text-align:center" class="blue3">2</td>
<td style="text-align:center" class="blue3">Botella d'aigua 50cL</td>
<td style="text-align:center" class="blue3">0.80</td>
</tr>
<!-- Sense categoria -->
<tr>
<td style="text-align:center" class="">NULL</td>
<td style="text-align:center" class="">NULL</td>
<td style="text-align:center" class="blue4">4</td>
<td style="text-align:center" class="blue4">NULL</td>
<td style="text-align:center" class="blue4">Piles AA</td>
<td style="text-align:center" class="blue4">1.50</td>
</tr>
<!-- 4 Fruta -->
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue5">5</td>
<td style="text-align:center" class="blue5">4</td>
<td style="text-align:center" class="blue5">Pera</td>
<td style="text-align:center" class="blue5">0.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue6">6</td>
<td style="text-align:center" class="blue6">4</td>
<td style="text-align:center" class="blue6">Plàtan</td>
<td style="text-align:center" class="blue6">0.50</td>
</tr>
</tbody>
</table>
Aquest resultat es pot obtindre mitjançant la consulta:
```sql
SELECT c.id_categoria, c.nom, p.id_producte, p.id_categoria, p.nom, p.preu
FROM categoria c
RIGHT JOIN producte p
ON p.id_categoria = c.id_categoria;
```
:::
## Combinació externa: `FULL JOIN`
La combinació externa `FULL JOIN` retorna aquells registres que estan relacionats en les dues taules (`INNER JOIN`),
però també retorna els valors de de les dues taules que no estan relacionats amb elements de l'altra taula (`LEFT JOIN` i `RIGHT JOIN`).
#7.1[FULL JOIN entre dos conjunts](/itb/DAM-BD/UD5/img/joins/full_join.svg)
No existeix la clàusula `FULL JOIN`, però podem obtindre el resultat mitjançant
la clàusula `UNION`, que retorna els registres presents en dues consultes:
```sql
SELECT columns
FROM table1 t1
LEFT JOIN table2 t2
ON t1.attr = t2.attr
UNION
SELECT columns
FROM table1 t1
RIGHT JOIN table2 t2
ON t1.attr = t2.attr
```
::: example
El `FULL JOIN` entre les taules Categoria i Producte ens retorna les categories relacionades amb els
productes que tenen, però també aquells productes que no tenen cap categoria i les categories que no tenen cap producte.
<table id="figure-5.2" class="center">
<caption>Figura 5.2: Resultat del LEFT JOIN entre les taules Producte i Categoria</caption>
<thead>
<tr>
<th style="text-align:center" colspan="2">Taula Categoria</th>
<th style="text-align:center" colspan="4">Taula Producte</th>
</tr>
<tr>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
<th style="text-align:center">ID Producte</th>
<th style="text-align:center">ID Categoria</th>
<th style="text-align:center">Nom</th>
<th style="text-align:center">Preu</th>
</tr>
</thead>
<tbody>
<!-- 1 Forn -->
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">1</td>
<td style="text-align:center" class="blue1">Barra de pà</td>
<td style="text-align:center" class="blue1">0.70</td>
</tr>
<tr>
<td style="text-align:center" class="orange1">1</td>
<td style="text-align:center" class="orange1">Forn</td>
<td style="text-align:center" class="blue2">2</td>
<td style="text-align:center" class="blue2">1</td>
<td style="text-align:center" class="blue2">Pastís de xocolate</td>
<td style="text-align:center" class="blue2">5.30</td>
</tr>
<!-- 2 Beguda -->
<tr>
<td style="text-align:center" class="orange2">2</td>
<td style="text-align:center" class="orange2">Beguda</td>
<td style="text-align:center" class="blue3">3</td>
<td style="text-align:center" class="blue3">2</td>
<td style="text-align:center" class="blue3">Botella d'aigua 50cL</td>
<td style="text-align:center" class="blue3">0.80</td>
</tr>
<!-- 3 Higiene -->
<tr>
<td style="text-align:center" class="orange3">3</td>
<td style="text-align:center" class="orange3">Higiene</td>
<td style="text-align:center" class="">NULL</td>
<td style="text-align:center" class="">NULL</td>
<td style="text-align:center" class="">NULL</td>
<td style="text-align:center" class="">NULL</td>
</tr>
<!-- Sense categoria -->
<tr>
<td style="text-align:center" class="">NULL</td>
<td style="text-align:center" class="">NULL</td>
<td style="text-align:center" class="blue4">4</td>
<td style="text-align:center" class="blue4">NULL</td>
<td style="text-align:center" class="blue4">Piles AA</td>
<td style="text-align:center" class="blue4">1.50</td>
</tr>
<!-- 4 Fruta -->
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue5">5</td>
<td style="text-align:center" class="blue5">4</td>
<td style="text-align:center" class="blue5">Pera</td>
<td style="text-align:center" class="blue5">0.30</td>
</tr>
<tr>
<td style="text-align:center" class="orange4">4</td>
<td style="text-align:center" class="orange4">Fruta</td>
<td style="text-align:center" class="blue6">6</td>
<td style="text-align:center" class="blue6">4</td>
<td style="text-align:center" class="blue6">Plàtan</td>
<td style="text-align:center" class="blue6">0.50</td>
</tr>
</tbody>
</table>
Aquest resultat es pot obtindre mitjançant la consulta:
```sql
SELECT c.id_categoria, c.nom, p.id_producte, p.id_categoria, p.nom, p.preu
FROM categoria c
LEFT JOIN producte p
ON p.id_categoria = c.id_categoria
UNION
SELECT c.id_categoria, c.nom, p.id_producte, p.id_categoria, p.nom, p.preu
FROM categoria c
RIGHT JOIN producte p
ON p.id_categoria = c.id_categoria;
```
:::
## Bibliografia
- https://es.wikipedia.org/wiki/Sentencia_JOIN_en_SQL
- https://stackoverflow.com/questions/4796872/how-can-i-do-a-full-outer-join-in-mysql