7. Joins

Los Joins nos permiten realizar consultas cuyo resultado puede estar formado por columnas de diferentes tablas. Esto es posible porque las tablas albergan una clave foránea, están relacionadas de alguna manera. De este modo podemos realizar consultas con datos de ambas tablas. No obstante, esta utilidad hay que usarla con precaución ya que consume muchos recursos.

Para la lección he creado una base de datos minimalista con fruta y colores.

Tablas de frutas

Puedes descargarla aquí.

Las tablas tienen la siguiente estructura:

erDiagram
    Frutas ||--o| Colores : "tiene color"
    Frutas {
        int FrutaId PK
        string Nombre
        int ColorId FK
    }
    Colores {
        int ColorId PK
        string Nombre
    }

Datos en Frutas: Melocotón (ColorId=3), Kiwi (ColorId=4), Coco (ColorId=5), Higo (ColorId=NULL), Manzana (ColorId=NULL)

Datos en Colores: 1-Rojo, 2-Amarillo, 3-Naranja, 4-Verde, 5-Marrón

INNER JOIN

El más conocido y utilizado. Une los valores que coinciden en ambas tablas si hay relación. En caso contrario omite la fila. Es una fusión horizontal, ya que combina columnas de 2 o más tablas ampliando los resultados "hacia los lados".

SELECT [tabla.columnas] FROM [tabla_1] INNER JOIN [tabla_2] ON [tabla_1.columna] = [tabla_2.columna];
SELECT * FROM Frutas INNER JOIN Colores ON Frutas.ColorId = Colores.ColorId;
FrutaId | Nombre | ColorId | ColorIColorId | Nombre
1   Melocotón   3   3   Naranja
2   Kiwi    4   4   Verde
3   Coco    5   5   Marrón

Para simplificar el resultado daremos algunos alias.

SELECT Frutas.Nombre AS Nombre, Colores.Nombre AS Color FROM Frutas INNER JOIN Colores ON Frutas.ColorId = Colores.ColorId;
Fruta | Color
Melocotón   Naranja
Kiwi    Verde
Coco    Marrón

Visualmente, INNER JOIN funciona así:

flowchart LR
    A["Frutas
━━━━━━━
✓ Melocotón (3)
✓ Kiwi (4)
✓ Coco (5)
✗ Higo (NULL)
✗ Manzana (NULL)"] B["Colores
━━━━━━━
✗ 1-Rojo
✗ 2-Amarillo
✓ 3-Naranja
✓ 4-Verde
✓ 5-Marrón"] C["Resultado
━━━━━━━
Melocotón-Naranja
Kiwi-Verde
Coco-Marrón"] A -->|"INNER JOIN
Solo coincidencias"| C B -->|"INNER JOIN
Solo coincidencias"| C

Mucho mejor, ¿no? Ahora te deberías estar preguntando: ¿Dónde está el Higo y la Manzana?. INNER JOIN es un solterón empedernido, ignora las relaciones que no van a ningún lado o las filas nulas.

LEFT JOIN

Une los valores de la primera tabla con la segunda, aunque encuentre relaciones rotas o Nulas. Básicamente no omite ninguna fila de la primera tabla. También es una fusión horizontal.

SELECT [tabla.columnas] FROM [tabla_1] LEFT JOIN [tabla_2] ON [tabla_1.columna] = [tabla_2.columna];
SELECT Frutas.Nombre AS Nombre, Colores.Nombre AS Color FROM Frutas LEFT JOIN Colores ON Frutas.ColorId = Colores.ColorId;
Fruta | Color
Melocotón   Naranja
Kiwi    Verde
Coco    Marrón
Higo    NULL
Manzana NULL

Visualmente, LEFT JOIN funciona así:

flowchart LR
    A["Frutas (TODAS)
━━━━━━━
✓ Melocotón (3)
✓ Kiwi (4)
✓ Coco (5)
✓ Higo (NULL)
✓ Manzana (NULL)"] B["Colores
━━━━━━━
✗ 1-Rojo
✗ 2-Amarillo
✓ 3-Naranja
✓ 4-Verde
✓ 5-Marrón"] C["Resultado
━━━━━━━
Melocotón-Naranja
Kiwi-Verde
Coco-Marrón
Higo-NULL
Manzana-NULL"] A -->|"LEFT JOIN
Todas de la izquierda"| C B -->|"Solo coincidencias"| C

RIGHT JOIN

Mismo mecanismo del anterior pero invertido. Une los valores de la segunda tabla con la primera. En este caso no omite filas de la segunda tabla. Continua siendo una fusión horizontal.

SELECT [tabla.columnas] FROM [tabla_1] RIGHT JOIN [tabla_2] ON [tabla_1.columna] = [tabla_2.columna];
SELECT Frutas.Nombre AS Nombre, Colores.Nombre AS Color FROM Frutas RIGHT JOIN Colores ON Frutas.ColorId = Colores.ColorId;
Fruta | Color
Melocotón   Naranja
Kiwi    Verde
Coco    Marrón
Higo    NULL
Manzana NULL

SQLite 3.12, y versiones anteriores, no son compatibles con RIGHT JOIN, por lo que no podremos visualizar un resultado real. Aunque conseguiremos el mismo efecto con LEFT JOIN y la tabla contraria.

SELECT Frutas.Nombre AS Nombre, Colores.Nombre AS Color FROM Frutas LEFT JOIN Colores ON Frutas.ColorId = Colores.ColorId;

FULL JOIN

No ignora ninguna fila, ni de la primera tabla ni de la segunda. Al igual que el sus semejantes, es una fusión horizontal.

SELECT [tabla.columnas] FROM [tabla_1] FULL OUTER JOIN [tabla_2] ON [tabla_1.columna] = [tabla_2.columna];
SELECT Frutas.Nombre AS Nombre, Colores.Nombre AS Color FROM Frutas FULL OUTER JOIN Colores ON Frutas.ColorId = Colores.ColorId;
Fruta | Color
Melocotón   Naranja
Kiwi    Verde
Coco    Marrón
NULL    Rojo
NULL    Amarillo
Higo    NULL
Manzana NULL

Visualmente, FULL OUTER JOIN funciona así:

flowchart LR
    A["Frutas (TODAS)
━━━━━━━
✓ Melocotón (3)
✓ Kiwi (4)
✓ Coco (5)
✓ Higo (NULL)
✓ Manzana (NULL)"] B["Colores (TODOS)
━━━━━━━
✓ 1-Rojo
✓ 2-Amarillo
✓ 3-Naranja
✓ 4-Verde
✓ 5-Marrón"] C["Resultado
━━━━━━━
Melocotón-Naranja
Kiwi-Verde
Coco-Marrón
Higo-NULL
Manzana-NULL
NULL-Rojo
NULL-Amarillo"] A -->|"FULL OUTER JOIN
Todas las filas"| C B -->|"FULL OUTER JOIN
Todas las filas"| C

SQLite 3.12, y versiones anteriores, no son compatibles con FULL OUTER JOIN, por lo que no podremos ver su resultado.

SQL UNION

Combina los valores de diferentes consultas en una sola columna o varias. Además suprime las repeticiones. Se considera una fusión vertical ya que apila consultas "hacia abajo", sumando las filas.

SELECT [tabla.columnas] FROM [tabla_1]
UNION
SELECT [tabla.columnas] FROM [tabla_2];

Es necesario que las columnas a mezclar se denominen con el mismo alias o nombre.

SELECT Frutas.nombre FROM Frutas
UNION
SELECT Colores.nombre FROM Colores
Nombre

Amarillo
Coco
Higo
Kiwi
Manzana
Marrón
Melocotón
Naranja
Rojo
Verde

En caso de necesitar que muestres los datos en crudo, sin eliminar las repeticiones, utiliza UNION ALL.

SELECT [tabla.columnas] FROM [tabla_1]
UNION ALL
SELECT [tabla.columnas] FROM [tabla_2];
SELECT Frutas.nombre FROM Frutas
UNION ALL
SELECT Colores.nombre FROM Colores
Actividad 1

De la tabla Invoice, consigue la siguiente información.

  1. Muestra: InvoiceId, nombre del cliente y BillingCountry.
  2. Ordena de mayor a menor por Total.
  3. Cual es el país que más a facturado.

Soluciones

This work is under a Attribution-NonCommercial-NoDerivatives 4.0 International license.

Desafíos de programación atemporales y multiparadigmáticos

Desafíos de programación atemporales y multiparadigmáticos

Te encuentras ante un librillo de actividades, divididas en 2 niveles de dificultad. Te enfrentarás a los casos más comunes que te puedes encontrar en pruebas técnicas o aprender conceptos elementales de programación.

Buy the book

Will you buy me a coffee?

Comments

There are no comments yet.

Visitors in real time

You are alone: 🐱