Join sin usar foreign key

Muchas veces creéis necesario realizar los joins usando exclusivamente campos que sean claves foráneas entre las tablas, o dicho de otra manera más informal, que hay que usar "los caminitos" que se ven en los diagramas del esquema de la BD). No es necesario; incluso, a veces, hacerlo puede suponer emplear tablas innecesarias que penalizan el rendimiento. Veámoslo en el siguiente ejemplo.

Supongamos que contamos con la BD de la figura, en la que tenemos empleados, que pertenecen a departamentos. Los departamentos tienes sedes en ciudades (un departamento puede tener varias sedes).

Empleado
+----+------+--------+
| id | dpto | ciudad |
+----+------+--------+
|  1 |    2 | Lugo   |
|  2 |    2 | Lugo   |
|  3 |    2 | Jaen   |
|  4 |    1 | Soria  |
+----+------+--------+
Departamento
+----+----------+
| id | nombre   |
+----+----------+
|  1 | Personal |
|  2 | Ventas   |
+----+----------+
Sede
+------+--------+
| dpto | ciudad |
+------+--------+
|    1 | Soria  |
|    2 | Jaen   |
|    2 | Úbeda  |
+------+--------+

Imaginemos que queremos encontrar aquellos empleados que viven en ciudades donde su departamento tiene sede.

Como hay que comparar los campos ciudad de las tablas Empleado y Sede, a la vista del esquema, podríamos pensar erróneamente que para "ir" de la tabla Empleado a Sede es necesario pasar por Departamento. No en vano, así lo indican las claves foráneas de las tablas (los enlaces que aparecen en el diagrama del esquema de la BD). Plantearíamos la consulta así:

MAL
select E.*
from Empleado E
    join Departamento D on E.dpto = D.id
    join Sede S on D.id = S.dpto and E.ciudad = S.ciudad;

En este caso, el uso de la tabla Departamento no es necesario, ya que hay un campo (Empleado.dpto) que permite relacionar directamente a empleados y sedes de los departamentos de los empleados. De este modo la consulta quedaría así:

BIEN
select E.*
from Empleado E
    join Sede S on E.dpto = S.dpto and E.ciudad = S.ciudad;

El resultado será:

+----+------+--------+
| id | dpto | ciudad |
+----+------+--------+
|  3 |    2 | Jaen   |
|  4 |    1 | Soria  |
+----+------+--------+

No hay comentarios:

Publicar un comentario