Sei sulla pagina 1di 6

Destripando el JOIN

by siqta

¿Cuál es la lógica que sigue el JOIN? Como entendía sólo por arriba cómo funcionaba, y no me
gusta hacer las cosas “sólo porque salen”, aproveché un feriado y me puse a hacer pruebas.

En un curso de la Khan Academy se explica como hacerlo


(https://www.khanacademy.org/computing/computer-programming/sql/relational-queries-in-
sql/p/combining-multiple-joins); pero ya digo, quería saber cómo funciona el comando. Así que
nada, nadie va a encontrar el descubrimiento de la pólvora aquí :-D

Base del curso de la Khan Academy (¡gracias pamela!):


CREATE TABLE students (id INTEGER PRIMARY KEY,
first_name TEXT,
last_name TEXT,
email TEXT,
phone TEXT,
birthdate TEXT);

INSERT INTO students (first_name, last_name, email, phone, birthdate)


VALUES ("Peter", "Rabbit", "peter@rabbit.com", "555-6666", "2002-06-24");
INSERT INTO students (first_name, last_name, email, phone, birthdate)
VALUES ("Alice", "Wonderland", "alice@wonderland.com", "555-4444", "2002-07-04");
INSERT INTO students (first_name, last_name, email, phone, birthdate)
VALUES ("Aladdin", "Lampland", "aladdin@lampland.com", "555-3333", "2001-05-10");
INSERT INTO students (first_name, last_name, email, phone, birthdate)
VALUES ("Simba", "Kingston", "simba@kingston.com", "555-1111", "2001-12-24");

CREATE TABLE student_projects (id INTEGER PRIMARY KEY,


student_id INTEGER,
title TEXT);

INSERT INTO student_projects (student_id, title)


VALUES (1, "Carrotapault");
INSERT INTO student_projects (student_id, title)
VALUES (2, "Mad Hattery");
INSERT INTO student_projects (student_id, title)
VALUES (3, "Carpet Physics");
INSERT INTO student_projects (student_id, title)
VALUES (4, "Hyena Habitats");

CREATE TABLE project_pairs (id INTEGER PRIMARY KEY,


project1_id INTEGER,
project2_id INTEGER);

INSERT INTO project_pairs (project1_id, project2_id)


VALUES(1, 2);
INSERT INTO project_pairs (project1_id, project2_id)
VALUES(3, 4);

La consigna es mostrar los resultados de la variable project_pairs interpretados, es decir, mostrando


los títulos de los proyectos y no los id.

Echamos un vistazo a ver qué datos hay:


Database Schema

students 4 rows student_projects 4 rows project_pairs 2 rows


id (PK) INTEGER id (PK) INTEGER id (PK) INTEGER
first_name TEXT student_id INTEGER project1_id INTEGER
last_name TEXT title TEXT project2_id INTEGER
email TEXT
phone TEXT
birthdate TEXT

Primero, obviamente, ubicamos los datos que precisamos:

SELECT * FROM project_pairs;


SELECT * FROM student_projects;

Nos muestra que tenemos todo lo necesario:

Results
id student_id title
1 1 Carrotapault
2 2 Mad Hattery
3 3 Carpet Physics
4 4 Hyena Habitats

id project1_id project2_id
1 1 2
2 3 4

La tarea es tan sencilla como hacer que se reemplacen en la tabla output de project_pairs los id por
los títulos (ya nos damos cuenta que student_projects.id 1 = “Carrotapault”, así que hay que armar
la tabla que empareje “carro” con “Mad Hattery” y “Carpet Physics” con “Hyena Habitats”, pero de
manera automática y con el malvado comando JOIN)

El primer paso es recontra lógico: como los datos que necesitamos están en distintas tablas, los
unimos (eso es lo que recomienda la profe):

SELECT * FROM project_pairs


JOIN student_projects;

Esto da este resultado:


Results
id project1_id project2_id id student_id title
1 1 2 1 1 Carrotapault
1 1 2 2 2 Mad Hattery
1 1 2 3 3 Carpet Physics
1 1 2 4 4 Hyena Habitats
2 3 4 1 1 Carrotapault
2 3 4 2 2 Mad Hattery
2 3 4 3 3 Carpet Physics
2 3 4 4 4 Hyena Habitats

Lo que dice la profe es que tenemos que cruzar OTRA VEZ con la tabla student_projects para que
los títulos aparezcan dos veces (?)

SELECT * FROM project_pairs


JOIN student_projects
JOIN student_projects;

Como con esto salta un problema de ambigüedad por la repetición del nombre de la tabla
student_project, le damos un alias a cada una:

SELECT * FROM project_pairs


JOIN student_projects a
JOIN student_projects b;

Con esto obtenemos esta hermosísima tabla:

Results
id project1_id project2_id id student_id title id student_id title
1 1 2 1 1 Carrotapault 1 1 Carrotapault
1 1 2 1 1 Carrotapault 2 2 Mad Hattery
1 1 2 1 1 Carrotapault 3 3 Carpet Physics
1 1 2 1 1 Carrotapault 4 4 Hyena Habitats
1 1 2 2 2 Mad Hattery 1 1 Carrotapault
1 1 2 2 2 Mad Hattery 2 2 Mad Hattery
1 1 2 2 2 Mad Hattery 3 3 Carpet Physics
1 1 2 2 2 Mad Hattery 4 4 Hyena Habitats
1 1 2 3 3 Carpet Physics 1 1 Carrotapault
1 1 2 3 3 Carpet Physics 2 2 Mad Hattery
1 1 2 3 3 Carpet Physics 3 3 Carpet Physics
1 1 2 3 3 Carpet Physics 4 4 Hyena Habitats
1 1 2 4 4 Hyena Habitats 1 1 Carrotapault
1 1 2 4 4 Hyena Habitats 2 2 Mad Hattery
id project1_id project2_id id student_id title id student_id title
1 1 2 4 4 Hyena Habitats 3 3 Carpet Physics
1 1 2 4 4 Hyena Habitats 4 4 Hyena Habitats
2 3 4 1 1 Carrotapault 1 1 Carrotapault
2 3 4 1 1 Carrotapault 2 2 Mad Hattery
2 3 4 1 1 Carrotapault 3 3 Carpet Physics
2 3 4 1 1 Carrotapault 4 4 Hyena Habitats
2 3 4 2 2 Mad Hattery 1 1 Carrotapault
2 3 4 2 2 Mad Hattery 2 2 Mad Hattery
2 3 4 2 2 Mad Hattery 3 3 Carpet Physics
2 3 4 2 2 Mad Hattery 4 4 Hyena Habitats
2 3 4 3 3 Carpet Physics 1 1 Carrotapault
2 3 4 3 3 Carpet Physics 2 2 Mad Hattery
2 3 4 3 3 Carpet Physics 3 3 Carpet Physics
2 3 4 3 3 Carpet Physics 4 4 Hyena Habitats
2 3 4 4 4 Hyena Habitats 1 1 Carrotapault
2 3 4 4 4 Hyena Habitats 2 2 Mad Hattery
2 3 4 4 4 Hyena Habitats 3 3 Carpet Physics
2 3 4 4 4 Hyena Habitats 4 4 Hyena Habitats

Disgresión
Esto duplicó las filas, por la combinatoria (¿son estas todas las muestras posibles, con
orden?)
Veamos cuántos son los valores posibles:

project_pairs.id 2
project_pairs.project1_id
project_pairs.project2_id
student_projects.id 4
student_projects.student_id
student_projects.title
El primer cruce, nos da 8 filas (2 * 4); el tercero, 16 (2 * 4 * 4 ).
Disgresión END

Lo que está combinando el JOIN son los casos, es decir, las filas. NO LOS VALORES
POSIBLES.
Entonces, los valores que “están juntos” en un caso determinado siempre lo acompañan. Por
ejemplo, vemos que cada vez que está Hyena en title hay id 4.

Comentario: esto está muy lindo con estos pocos casos; pero ¿si hay una base grande? ¿¿cruza todo
con todo?? En fin.

Ahora hay que armar la conexión entre tablas, para descartar lo que no cruza según el esquema de la
tabla project_pairs:
Results
id project1_id project2_id id student_id title id student_id title
1 1 2 1 1 Carrotapault 1 1 Carrotapault
1 1 2 1 1 Carrotapault 2 2 Mad Hattery
1 1 2 1 1 Carrotapault 3 3 Carpet Physics
1 1 2 1 1 Carrotapault 4 4 Hyena Habitats
1 1 2 2 2 Mad Hattery 1 1 Carrotapault
1 1 2 2 2 Mad Hattery 2 2 Mad Hattery
1 1 2 2 2 Mad Hattery 3 3 Carpet Physics
1 1 2 2 2 Mad Hattery 4 4 Hyena Habitats
1 1 2 3 3 Carpet Physics 1 1 Carrotapault
1 1 2 3 3 Carpet Physics 2 2 Mad Hattery
1 1 2 3 3 Carpet Physics 3 3 Carpet Physics
1 1 2 3 3 Carpet Physics 4 4 Hyena Habitats
1 1 2 4 4 Hyena Habitats 1 1 Carrotapault
1 1 2 4 4 Hyena Habitats 2 2 Mad Hattery
1 1 2 4 4 Hyena Habitats 3 3 Carpet Physics
1 1 2 4 4 Hyena Habitats 4 4 Hyena Habitats
2 3 4 1 1 Carrotapault 1 1 Carrotapault
2 3 4 1 1 Carrotapault 2 2 Mad Hattery
2 3 4 1 1 Carrotapault 3 3 Carpet Physics
2 3 4 1 1 Carrotapault 4 4 Hyena Habitats
2 3 4 2 2 Mad Hattery 1 1 Carrotapault
2 3 4 2 2 Mad Hattery 2 2 Mad Hattery
2 3 4 2 2 Mad Hattery 3 3 Carpet Physics
2 3 4 2 2 Mad Hattery 4 4 Hyena Habitats
2 3 4 3 3 Carpet Physics 1 1 Carrotapault
2 3 4 3 3 Carpet Physics 2 2 Mad Hattery
2 3 4 3 3 Carpet Physics 3 3 Carpet Physics
2 3 4 3 3 Carpet Physics 4 4 Hyena Habitats
2 3 4 4 4 Hyena Habitats 1 1 Carrotapault
2 3 4 4 4 Hyena Habitats 2 2 Mad Hattery
2 3 4 4 4 Hyena Habitats 3 3 Carpet Physics
2 3 4 4 4 Hyena Habitats 4 4 Hyena Habitats

Vamos por partes, para ver cómo funciona:

SELECT * FROM project_pairs


JOIN student_projects a
ON project_pairs.project1_id = a.id
JOIN student_projects b;

(En el ON tenemos que especificar el alias, no el nombre original de la variable)


Results
id project1_id project2_id id student_id title id student_id title
1 1 2 1 1 Carrotapault 1 1 Carrotapault
1 1 2 1 1 Carrotapault 2 2 Mad Hattery
1 1 2 1 1 Carrotapault 3 3 Carpet Physics
1 1 2 1 1 Carrotapault 4 4 Hyena Habitats
2 3 4 3 3 Carpet Physics 1 1 Carrotapault
2 3 4 3 3 Carpet Physics 2 2 Mad Hattery
2 3 4 3 3 Carpet Physics 3 3 Carpet Physics
2 3 4 3 3 Carpet Physics 4 4 Hyena Habitats

Con esto ya coinciden project.pairs.project1_id con student.projects (alias “a”)

Vamos entonces a por la b:

SELECT * FROM project_pairs


JOIN student_projects a
ON project_pairs.project1_id = a.id
JOIN student_projects b
ON project_pairs.project2_id = b.id;

Results
id project1_id project2_id id student_id title id student_id title
1 1 2 1 1 Carrotapault 2 2 Mad Hattery
2 3 4 3 3 Carpet Physics 4 4 Hyena Habitats

¡Ya está lo principal! Restan cuestiones “estéticas”: quitar las variables que no sirven, y poner
rótulos de columna un poco menos ambiguos

SELECT a.title AS “Título Proyecto 1”, b.title AS “Título Proyecto 2” FROM project_pairs
JOIN student_projects a
ON project_pairs.project1_id = a.id
JOIN student_projects b
ON project_pairs.project2_id = b.id;

Results
“Título_Proyecto_1” “Título_Proyecto_2”
Carrotapault Mad Hattery
Carpet Physics Hyena Habitats

Potrebbero piacerti anche