Unir tablas en SQL con JOIN
Tags: sql, join, sqlite3
Published: 2023-06-19 15:35:58

El concepto de **“JOIN”** en **SQL** se utiliza para combinar registros de dos o más tablas en función de una condición relacionada entre ellas. El resultado es una nueva tabla que contiene columnas de ambas tablas, seleccionadas según la condición de unión especificada. Esto permite relacionar y vincular datos de diferentes tablas, lo que es fundamental para realizar consultas complejas y obtener información completa.

Para comprender mejor el funcionamiento de **“JOIN”**, es útil entender la _teoría de conjuntos_ en la que se basa.

La teoría de conjuntos se refiere a operaciones como unión, intersección y diferencia que se pueden aplicar a conjuntos de elementos.

Estos conceptos se aplican en el contexto de las tablas de bases de datos relacionales. A continuación, se explican los diferentes tipos de **“JOIN”** junto con ejemplos y su relación con la teoría de conjuntos:

Para realizar los ejemplos se tomará como base las siguientes tablas:

## 1. Tabla Clientes

Se crea una tabla de clientes con 3 campos id_cliente, nombre y email.

```sql
CREATE TABLE IF NOT EXISTS clientes(
id_cliente integer PRIMARY KEY AUTOINCREMENT,
nombre text,
email text
);
```

## 2. Tabla ventas


Se crea una tabla de ventas con los campos id_venta, id_cliente y fecha, además de una relación con la tabla de clientes.

```sql
CREATE TABLE IF NOT EXISTS ventas(
id_venta integer PRIMARY KEY AUTOINCREMENT,
id_cliente integer,
fecha text
);
```

## 3. Insertar registros en la tabla Clientes

Para las pruebas se anexan 3 clientes.

```sql
INSERT INTO clientes(nombre,email)
VALUES
('Dejah','dejah@email.com'),
('John','john@email.com'),
('Carthoris','carthoris@email.com');
```

## 4. Insertar registros en la tabla ventas

Para las pruebas se anexan 5 registros, se puede notar que el cliente Carthoris no ha realizado ninguna compra en la tienda (venta).

```sql
INSERT INTO ventas(id_cliente,fecha)
VALUES
(2,"6/6/2023"),
(2,"7/6/2023"),
(1,"8/6/2023"),
(1,"9/6/2023"),
(1,"9/6/2023"),
(4,"9/6/2023");
```

**Nota:** Si se tiene un diseño correcto de base de datos y se hubiera agregado la restricción **REFERENCES** entre las tablas clientes y ventas, para evitar hacer ventas a clientes que no están registrados no sería posible agregar la venta al cliente 4, pero en este caso no se agrego la restricción con fines de ejemplificar los JOIN.

## 5. INNER JOIN (JOIN):

El **“INNER JOIN”** combina registros de ambas tablas que tienen una coincidencia en la columna de unión especificada. Esta unión devuelve solo los registros que cumplen con la condición de igualdad.

**Ejemplo:** Se quieren obtener todas las ventas realizadas junto con los nombres de los clientes correspondientes. Para esta consulta se puede usar un “INNER JOIN” de la siguiente manera:

```sql
SELECT ventas.*, clientes.nombre
FROM ventas
INNER JOIN clientes ON ventas.id_cliente = clientes.id_cliente;
```

Esta consulta combina los registros de la tabla **“ventas”** con los registros de la tabla **“clientes”** donde los valores de la columna “id_cliente” coinciden en ambas tablas como se muestra en la Imagen 1. 

El resultado será una nueva tabla que contiene los detalles de las ventas junto con los nombres de los clientes correspondientes.


![Imagen 1: Resultado de INNER JOIN.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i6jv2mem8jivuzoceh33.png)
Imagen 1: Resultado de INNER JOIN.


## 6. LEFT JOIN (LEFT OUTER JOIN):

El **“LEFT JOIN”** combina todos los registros de la tabla izquierda (primera tabla en la cláusula JOIN) con los registros coincidentes de la tabla derecha (segunda tabla en la cláusula JOIN).

Si no hay coincidencias en la tabla derecha, se devolverán **NULL** en las columnas de la tabla derecha.

**Ejemplo:** Se desea obtener todos los clientes junto con las ventas realizadas por cada uno (si existen), se puede utilizar un “LEFT JOIN” de la siguiente manera:

```sql
SELECT clientes.*, ventas.fecha
FROM clientes
LEFT JOIN ventas ON clientes.id_cliente = ventas.id_cliente;
```

Esta consulta combina todos los registros de la tabla **“clientes”** con los registros coincidentes de la tabla **“ventas”** en función de la igualdad de los valores en la columna **“id_cliente”**.

Incluso si un cliente no tiene ventas registradas, se devolverá su información junto con NULL en las columnas relacionadas de la tabla **“ventas”** tal como se muestra en la Imagen 2.


![Imagen 2: Resultado de LEFT JOIN.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p1sapg5e8e6426e0iq43.png)
Imagen 2: Resultado de LEFT JOIN.

## 7. RIGHT JOIN (RIGHT OUTER JOIN)

El **“RIGHT JOIN”** combina todos los registros de la tabla derecha con los registros coincidentes de la tabla izquierda. Si no hay coincidencias en la tabla izquierda, se devolverán NULL en las columnas de la tabla izquierda.

**Ejemplo:** Si se quieren obtener todas las ventas junto con la información de los clientes correspondientes (si existe), se puede utilizar un “RIGHT JOIN” de la siguiente manera:

```sql
SELECT ventas.*, clientes.nombre
FROM clientes
RIGHT JOIN ventas ON ventas.id_cliente = clientes.id_cliente;
```

Esta consulta combina todos los registros de la tabla **“ventas”** con los registros coincidentes de la tabla **“clientes”** basados en la igualdad de los valores en la columna **“id_cliente”**.

Incluso si una venta no está asociada con un cliente, se devolverá su información junto con NULL en las columnas relacionadas de la tabla “clientes” tal como se muestra en la Imagen 3.


![Imagen 3: Resultado RIGTH JOIN.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6s0llfdehurfyud5ici.png)
Imagen 3: Resultado RIGTH JOIN.

## 8. Resumen

En resumen, el concepto de **“JOIN”** en **SQL** permite combinar registros de diferentes tablas en función de condiciones de igualdad.

Los diferentes tipos de **“JOIN”** (INNER, LEFT y RIGHT) ofrecen flexibilidad para obtener información específica de acuerdo con las relaciones entre las tablas.

Estos tipos de **“JOIN”** se basan en la teoría de conjuntos para combinar conjuntos de datos y proporcionar resultados más completos y relacionados.