PDA

Ver la Versión Completa : Problema con 2 joins mismos campos


Toni
21-04-2009, 14:54:44
Hola,

Tengo un problema con una consulta en la que realizo dos joins, y el problema es que solo me devuelve los registros del segundo join. Y el resultado que busco es que me devuelva todos los registros de la tablaA con los datos que coincidan de las otras tablas.

SELECT "TablaA."."Campo1", "TablaB."."Campo1", "TablaC."."Campo1"
FROM "TablaA"
LEFT OUTER JOIN "TablaB" ON (("TablaA"."idDocumento" = "TablaB"."idDocumento") AND ("TablaA"."Flag" = 'B'))
LEFT OUTER JOIN "TablaC" ON (("TablaA"."idDocumento" = "TablaC"."idDocumento") AND ("TablaA"."Flag" = 'C'))

La consulta funciona bien si solo utilizo uno de los joins, creo que lo que da problemas es que utilizo en la condicion los mismo campos de la TablaA.

Estoy utilizando interbase 6.0 y desde C++ Builder 6.0 con componentes IBX.

Saludos.

Nota: Si en las condiciones de los dos joins quito la comparacion "TablaA"."Flag" = 'C', el resultado que da la consulta es casi el deseado. Por lo menos retorna todos lo registros de la TablaA. Lo unico que confunde los documentos de un tipo y de otro.

ContraVeneno
21-04-2009, 16:36:19
SELECT "TablaA."."Campo1", "TablaB."."Campo1", "TablaC."."Campo1"
FROM "TablaA"
LEFT OUTER JOIN "TablaB" ON (("TablaA"."idDocumento" = "TablaB"."idDocumento"))
LEFT OUTER JOIN "TablaC" ON (("TablaA"."idDocumento" = "TablaC"."idDocumento"))
where "TablaA"."Flag" in ('B', 'C')

Toni
21-04-2009, 18:37:37
Hola ContraVeneno,

Primero muchas gracias por tu contestacion.

Pero quizas no me explique del todo bien, en la TablaA hay muchos registros con valores distintos para el campo Flag ('A','B,'C','D'...) y quiero que en la consulta me los muestre todos.

Pero en el caso de un registro con valor 'B' vaya a buscar solo a la TablaB y si el valor es 'C' a la TablaC, otros valores no los buscara en tablas anexas y mostrara los campos TablaB.Campo1, TablaC.Campo1 como null.

Por eso esta añadido a la condicion del join la comparacion de valor del Flag, que de hecho si solo dejo uno de los join funciona bien, pero claro me hace falta contra las dos tablas y no veo el porque.

Saludos

duilioisola
21-04-2009, 18:38:23
Si quieres los datos de la TablaA que también tengan datos en las otras dos tablas, deberás utilizar "JOIN" y no "LEFT OUTER JOIN".
También puedes probar utilizando "LEFT JOIN"


SELECT "TablaA."."Campo1", "TablaB."."Campo1", "TablaC."."Campo1"
FROM "TablaA"
JOIN "TablaB" ON (("TablaA"."idDocumento" = "TablaB"."idDocumento") AND ("TablaA"."Flag" = 'B'))
JOIN "TablaC" ON (("TablaA"."idDocumento" = "TablaC"."idDocumento") AND ("TablaA"."Flag" = 'C'))



SELECT "TablaA."."Campo1", "TablaB."."Campo1", "TablaC."."Campo1"
FROM "TablaA"
LEFT JOIN "TablaB" ON (("TablaA"."idDocumento" = "TablaB"."idDocumento") AND ("TablaA"."Flag" = 'B'))
LEFT JOIN "TablaC" ON (("TablaA"."idDocumento" = "TablaC"."idDocumento") AND ("TablaA"."Flag" = 'C'))

ContraVeneno
21-04-2009, 18:49:39
pero lo que se requiere son "Todos" los registros de la TablaA, por lo que el "left outer join" es correcto...

Toni
21-04-2009, 18:52:04
Hola duilioisola,

Muchas gracias por tu contestacion.

Lo he probado pero no funciona bien, no retorna ningun registro en este caso.

Esto es una cosa que ya he realizado habitualmente y siempre me ha funcionado anexar tablas externas con left outer join. La unica diferencia que hay en este caso y la que me provoca el problema es que las dos tablas se anexan con un mismo campo de la tabla principal y en funcion del valor de un Flag debe anexar con una o con otra y si el flag tienen otro valor diferente mostrar el registro igualmente.

Es curioso porque solo muestra los registros coincidentes con el segundo join!!

Saludos.

duilioisola
21-04-2009, 19:30:06
Acabp de hacer esta prueba:

Tabla TA
CAMPO1 IDDOCUMENTO FLAG
1 1 A
2 2 C
3 3 C
1 1 B
2 2 B
Tabla TB
CAMPO1 IDDOCUMENTO
1 1
2 2
3 3
Tabla TC
CAMPO1 IDDOCUMENTO
1 1
2 2

SELECT A.CAMPO1,B.CAMPO1,C.CAMPO1
FROM TA A
LEFT OUTER JOIN TB B ON ((A.iddocumento=B.iddocumento) AND (A.flag='B'))
LEFT OUTER JOIN TC C ON ((A.iddocumento=C.iddocumento) AND (A.flag='C'))

CAMPO1 CAMPO11 CAMPO12
1 null null
1 1 null
2 null 2
2 2 null
3 null null

Toni
21-04-2009, 22:06:07
Este problema ya me resultaba algo extraño, pero al decirme que a ti te funciona correctamente he pensado que quizas fuese la version del servidor de base de datos. Yo estoy utilizando Interbase 6.0 en este equipo donde no me funciona, he copiado la base de datos a otro ordenador que tengo instalado Firebird 1.5 y me funciona correctamente la consulta SQL que me daba el problema.

Por lo que parece ser un problema en el Interbase 6.0.

Muchas gracias por vuestra ayuda.