unir - SQL uniendo tres tablas, uniendo precedencia
unir dos consultas sql misma tabla (4)
Cuando te unes a la tercera tabla, tu primera consulta
SELECT
*
FROM
R
JOIN S ON (S.id = R.fks)
es como una tabla derivada a la que te estás uniendo a la tercera tabla. Por lo tanto, si R JOIN S
no produce filas, la unión a P
nunca generará filas (porque estás intentando unirte a una tabla vacía).
Por lo tanto, si está buscando reglas de precedencia, en este caso solo se establece utilizando LEFT JOIN
en lugar de JOIN
.
Sin embargo, es posible que no entienda bien su pregunta, ya que si escribiera la consulta, cambiaría S
y R
p.ej.
SELECT
*
FROM
S
JOIN R ON (S.id = R.fks)
Tengo tres tablas: R, S y P.
La tabla R se une con S a través de una clave externa; debería haber al menos un registro en S, para que pueda UNIRME:
SELECT
*
FROM
R
JOIN S ON (S.id = R.fks)
Si no hay registro en S, entonces no obtengo filas, eso está bien.
Luego, la tabla S se une con P, donde los registros es P pueden o no estar presentes y unirse con S.
Así que hago
SELECT
*
FROM
R
JOIN S ON (S.id = R.fks)
LEFT JOIN P ON (P.id = S.fkp)
¿Qué pasa si quisiera que el segundo JOIN esté vinculado a S no a R, como si pudiera usar paréntesis?
SELECT
*
FROM
R
JOIN (S ON (S.id = R.fks) JOIN P ON (P.id = S.fkp))
¿O es que ya es un comportamiento natural del producto cartesiano entre R, S y P?
La segunda unión está vinculada a S a medida que el estado explícito JOIN P ON (P.id = S.fkp)
: no se hace referencia a ninguna columna de R en la unión.
Todos los tipos de uniones externas y normales están en la misma clase de precedencia y los operadores tienen efecto de izquierda a derecha en un nivel de anidamiento dado de la consulta. Puede poner la expresión de unión en el lado derecho entre paréntesis para que tenga efecto primero; solo recuerda que tienes que mover la cláusula ON
de la unión que ahora está fuera de la unión en la que pones parens.
(Ejemplo de PostgreSQL)
En SELECT * FROM a LEFT JOIN b ON (a.id = b.id) JOIN c ON (b.ref = c.id);
la unión ab tiene efecto primero, pero podemos forzar que la unión bc tenga efecto primero poniéndola entre paréntesis, que parece:
SELECT * FROM a LEFT JOIN (b JOIN c ON (b.ref = c.id)) ON (a.id = b.id);
A menudo puede expresar lo mismo sin paréntesis adicionales moviendo las uniones y cambiando la dirección de la unión externa, por ejemplo,
SELECT * FROM b JOIN c ON (b.ref = c.id) RIGHT JOIN a ON (a.id = b.id);
with a as (select 1 as test union select 2)
select * from a left join
a as b on a.test=b.test and b.test=1 inner join
a as c on b.test=c.test
go
with a as (select 1 as test union select 2)
select * from a inner join
a as b on a.test=b.test right join
a as c on b.test=c.test and b.test=1
Idealmente, esperamos que las dos consultas anteriores sean iguales. Sin embargo, no lo son, por lo que cualquier persona que diga que una unión a la derecha puede ser reemplazada por una a la izquierda en todos los casos es incorrecta. Solo utilizando la unión correcta podemos obtener el resultado requerido.