PDA

Ver la Versión Completa : LEFT JOIN extraños?


Gydba
07-05-2004, 15:58:10
Buenas,

Tengo una consulta un tanto extraña que no me está funcionando, en particular el LEFT JOIN parece estar trabajando de manera poco natural
Es decir, por lógica el LEFT JOIN no debería estar restringiendo los resultados de la tabla T1, sin embargo esto no es así. La consulta en particular es:

select t1.dummy
from dual t1
left join dual t2 on 'Hola'=t2.dummy

He probado lo mismo con Firebird y me funcionó como era de esperar. Hemos hecho otras pruebas sobre Oracle y lo que nos resultó positivo fué lo siguiente:

select t1.dummy
from dual t1
left join dual t2 on 'Hola'=t2.dummy
and t1.dummy = t1.dummy

Al parecer, pudimos concluir en base a la observación directa, que si no se incluye una columna de la tabla T1 (la tabla del FROM) en la condición del LEFT JOIN, éste funciona como un JOIN común.
Según lo anterior esto funciona bien:

select t1.dummy
from dual t1
left join dual t2 on t1.dummy || 'Jamon' =t2.dummy

La versión de Oracle que estamos utilizando es: 9i release 9.2.0.1.0

¿A alguien le ha pasado algo similar?

jachguate
07-05-2004, 18:25:53
Buenas,

Tengo una consulta un tanto extraña que no me está funcionando, en particular el LEFT JOIN parece estar trabajando de manera poco natural

A que te referis con "poco natural"??

He probado lo mismo con Firebird y me funcionó como era de esperar.
Como era de esperar para firebird, supongo...

Quizas lo que vos estes intentando hacer sea un natural join

Probá con esta sintaxis (no garantizo que funcione de todas formas, pues dependerá de la estructura de tus tablas).


select t1.dummy
from dual t1
natural left join dual t2
where 'Hola' = t2.dummy


Esta sintaxis es válida (al igual que la del left join) a partir de 9i

Hasta luego.

;)

Gydba
07-05-2004, 19:39:16
Creo que es un error de interpretación, yo particularmente no quiero hacer un natural JOIN (pensé que en el primer SELECT de ejemplo que puse quedaba claro), de hecho la solución a este problema sería replantear de otra manera mis consultas para evitar estos inconvenientes.

Mas que nada quería saber si a alguien le pasó esto en Oracle, porque o yo estoy loco (que es muy factible :)) o un LEFT JOIN no debería comportarse así, sino ¿Cuál es la definición de un LEFT JOIN?

Gracias de antemano.

jachguate
07-05-2004, 21:12:11
pensé que en el primer SELECT de ejemplo que puse quedaba claro
Pues a mi me quedo la duda... y me parecia que mas que todo, lo que querias era eso :p

¿Cuál es la definición de un LEFT JOIN?

esto:

An outer join extends the result of a simple join. An outer join returns all rows that satisfy the join condition and also returns some or all of those rows from one table for which no rows from the other satisfy the join condition.

* To write a query that performs an outer join of tables A and B and returns all rows from A (a left outer join), use the LEFT [OUTER] JOIN syntax in the FROM clause, or apply the outer join operator (+) to all columns of B in the join condition in the WHERE clause. For all rows in A that have no matching rows in B, Oracle returns null for any select list expressions containing columns of B.
* To write a query that performs an outer join of tables A and B and returns all rows from B (a right outer join), use the RIGHT [OUTER] JOIN syntax in the FROM clause, or apply the outer join operator (+) to all columns of A in the join condition in the WHERE clause. For all rows in B that have no matching rows in A, Oracle returns null for any select list expressions containing columns of A.
* To write a query that performs an outer join and returns all rows from A and B, extended with nulls if they do not satisfy the join condition (a full outer join), use the FULL [OUTER] JOIN syntax in the FROM clause.


El problema aqui, es cual es la join condition. Se sobreentiende que será una expresión que relacione al menos un campo de cada tabla... porque hacer algo como:

Select a.campo1, b.campo2
from a left outer join b on b.Campo1 = 'CualquierCosa'

no parece un outer join... parece simplemente un encuentro cartesiano de las tablas, que igual se puede conseguir sin un outer join


Select a.campo1, b.campo2
from a, b
where b.campo1 = 'cualquiercosa'


Pues en realidad no hay nada que "relacione" las tablas... o estoy equivocado??

Hasta luego.

;)

Gydba
07-05-2004, 22:29:59
Bueno jachguate antes que nada gracias por tu tiempo.

Ahora, como bien decís vos es un poco ilógico hacer una relación de campos que no mantengan relación (valga la redundancia del juego de palabras :))

Sin embargo esta prueba la he realizado en otros motores como SQL Server y FB 1.5 y estos no me restringen los resultado de la tabla master (es decir la del FROM) respetando el tipo de JOIN que realizo.

Por eso lo que yo buscaba era la explicación correcta de como debería funcionar un JOIN de este tipo y porque el motor de Oracle no resuelve esto de la misma manera que los otros motores probados con lo mismo.

Demás decir que los ejemplos que puse son a modo de simplificación puesto que el problema original apareció de una migración de SQL Server a Oracle, donde hay varios triggers y SPs que empezaron a fallar en Oracle y con algunas correciones ya funcionan.

Nuevamente gracias por tu aporte

jachguate
07-05-2004, 23:11:32
Sin embargo esta prueba la he realizado en otros motores como SQL Server y FB 1.5 y estos no me restringen los resultado de la tabla master (es decir la del FROM) respetando el tipo de JOIN que realizo.

Habrá que revisar si el estándar se pronuncia al respecto... no me extrañaría que oracle arbitrariamente decidiera hacerlo de esta forma. Aunque la verdad... yo no la veo tan descabellada. Te he dicho ya que un outer join sin join condition, no es mas que un producto cartesiano de las tablas... y creo que asi debiera plantearse naturalmente. Es que hacer un join de esta forma me parece algo (discupla la expresión) retorcido.

Por eso lo que yo buscaba era la explicación correcta de como debería funcionar un JOIN de este tipoLa explicación correcta debiera estar en el estándar. Si es un punto que no está estandarizado, supongo que cada motor hará lo que le venga en gana (o le convenga, o le parezca lógico o correcto, como se prefiera).

y porque el motor de Oracle no resuelve esto de la misma manera que los otros motores probados con lo mismo.
Pues no será la primera vez que Oracle imponga su propio criterio, incluso sobre el estándar... (si no, revisá el tipo Date, que es en realidad un TimeStamp... )

Nuevamente gracias por tu aporte

No hay de que... aunque un par de chelas no me carian mal... :D

Hasta luego.

;)