Consulta SQL con OUTER JOINS que no devuelve lo esperado.

21/11/2005 - 13:24 por Pau Domínguez | Informe spam
Hola a todos.
Tengo un programa que ejecuta una consulta SQL con outer joins que no
devuelve lo que se supone que debería.
El problema es el siguientes.
Tengo una consulta sobre 5 tablas llamemoslas A,B,C,D,E
A y B tienen una relacion maestro detalle pero hay registros en A sin
detalle en B.
Las demás tablas, son tablas maestras que contienen información sobre campos
de A y B en concreto C y D sobre campos de A y E sobre campos de B.
Estas tres tablas están enlazadas con claves primarias y no hay problemas de
integridad referencial en los datos.

La consulta tiene que devolver todos los registros de A y cuando existan
registros detalle en B solo los que cumplan un filtro en la tabla E.

En principio no parecía que tubiera que habler ningún problema la sonsulta
sería algo así:
Select distinct a.*
from A inner join C on A.FK1 = C.PK
inner join D on A.FK2 = D.PK
right outer join B on A.FK3 = B.FK1
right outer join E on b.FK2 = E.PK
where condicion sobre campos de C
and condiciones sobre campos de E

Pues bien, la consulta no devueve los mismos registros si aparacen las
condiciones sobre campos de E como si los omito.
(Las condiciones sobre E incluyen un "or e.campo is null"). Aunque según
entiendo yo, el right outer join obliga a devolver todos los registro de la
tabla A
independientemente de los filtros sobre las tablas de la izquierda, cosa que
no está pasando.

Parece ser que cuando todos los registros detalle que exiten en B no cumplen
el filtro no se muestra tampoco el registro de A.
¿No va esto en contra de lo que se supone que hace el OUTER JOIN?

Gracias.

Pau.

Preguntas similare

Leer las respuestas

#1 Alejandro Mesa
21/11/2005 - 15:08 | Informe spam
Pau Domínguez,

Me parece, segun lo que comentastes, que debes usar "left join" en vez de
"right join".

...
right outer join B on A.FK3 = B.FK1
right outer join E on b.FK2 = E.PK
...


AMB

"Pau Domínguez" wrote:

Hola a todos.
Tengo un programa que ejecuta una consulta SQL con outer joins que no
devuelve lo que se supone que debería.
El problema es el siguientes.
Tengo una consulta sobre 5 tablas llamemoslas A,B,C,D,E
A y B tienen una relacion maestro detalle pero hay registros en A sin
detalle en B.
Las demás tablas, son tablas maestras que contienen información sobre campos
de A y B en concreto C y D sobre campos de A y E sobre campos de B.
Estas tres tablas están enlazadas con claves primarias y no hay problemas de
integridad referencial en los datos.

La consulta tiene que devolver todos los registros de A y cuando existan
registros detalle en B solo los que cumplan un filtro en la tabla E.

En principio no parecía que tubiera que habler ningún problema la sonsulta
sería algo así:
Select distinct a.*
from A inner join C on A.FK1 = C.PK
inner join D on A.FK2 = D.PK
right outer join B on A.FK3 = B.FK1
right outer join E on b.FK2 = E.PK
where condicion sobre campos de C
and condiciones sobre campos de E

Pues bien, la consulta no devueve los mismos registros si aparacen las
condiciones sobre campos de E como si los omito.
(Las condiciones sobre E incluyen un "or e.campo is null"). Aunque según
entiendo yo, el right outer join obliga a devolver todos los registro de la
tabla A
independientemente de los filtros sobre las tablas de la izquierda, cosa que
no está pasando.

Parece ser que cuando todos los registros detalle que exiten en B no cumplen
el filtro no se muestra tampoco el registro de A.
¿No va esto en contra de lo que se supone que hace el OUTER JOIN?

Gracias.

Pau.




Respuesta Responder a este mensaje
#2 Pau Domínguez
21/11/2005 - 16:36 | Informe spam
Perdonad.
La consulta la tengo con LEFT OUTER JOIN no con right outer join como os he
puesto.
He hecho tantas pruebas que se me ha ido el santo al cielo.

Select distinct a.*
from A inner join C on A.FK1 = C.PK
inner join D on A.FK2 = D.PK
LEFT outer join B on A.FK3 = B.FK1
LEFT outer join E on b.FK2 = E.PK
where condicion sobre campos de C
and condiciones sobre campos de E





Gracias de todas formas.
Pau.


"Alejandro Mesa" escribió en el
mensaje news:
Pau Domínguez,

Me parece, segun lo que comentastes, que debes usar "left join" en vez de
"right join".

...
right outer join B on A.FK3 = B.FK1
right outer join E on b.FK2 = E.PK
...


AMB

"Pau Domínguez" wrote:

Hola a todos.
Tengo un programa que ejecuta una consulta SQL con outer joins que no
devuelve lo que se supone que debería.
El problema es el siguientes.
Tengo una consulta sobre 5 tablas llamemoslas A,B,C,D,E
A y B tienen una relacion maestro detalle pero hay registros en A sin
detalle en B.
Las demás tablas, son tablas maestras que contienen información sobre
campos
de A y B en concreto C y D sobre campos de A y E sobre campos de B.
Estas tres tablas están enlazadas con claves primarias y no hay problemas
de
integridad referencial en los datos.

La consulta tiene que devolver todos los registros de A y cuando existan
registros detalle en B solo los que cumplan un filtro en la tabla E.

En principio no parecía que tubiera que habler ningún problema la
sonsulta
sería algo así:
Select distinct a.*
from A inner join C on A.FK1 = C.PK
inner join D on A.FK2 = D.PK
right outer join B on A.FK3 = B.FK1
right outer join E on b.FK2 = E.PK
where condicion sobre campos de C
and condiciones sobre campos de E

Pues bien, la consulta no devueve los mismos registros si aparacen las
condiciones sobre campos de E como si los omito.
(Las condiciones sobre E incluyen un "or e.campo is null"). Aunque según
entiendo yo, el right outer join obliga a devolver todos los registro de
la
tabla A
independientemente de los filtros sobre las tablas de la izquierda, cosa
que
no está pasando.

Parece ser que cuando todos los registros detalle que exiten en B no
cumplen
el filtro no se muestra tampoco el registro de A.
¿No va esto en contra de lo que se supone que hace el OUTER JOIN?

Gracias.

Pau.




Respuesta Responder a este mensaje
#3 Alejandro Mesa
21/11/2005 - 16:58 | Informe spam
Pau,

Para poder reproducir el problema, poder analizarlo y poder recomendar algo,
creo que sera mejor si te armas un script con la definicion de las tablas,
unas filas de ejemplo y cual seria el resultado esperado. Como haz de saber,
es casi imposible recomendar algo si no tenemos idea de lo que puede estar
pasando.


AMB

"Pau Domínguez" wrote:

Perdonad.
La consulta la tengo con LEFT OUTER JOIN no con right outer join como os he
puesto.
He hecho tantas pruebas que se me ha ido el santo al cielo.

>> Select distinct a.*
>> from A inner join C on A.FK1 = C.PK
>> inner join D on A.FK2 = D.PK
>> LEFT outer join B on A.FK3 = B.FK1
>> LEFT outer join E on b.FK2 = E.PK
>> where condicion sobre campos de C
>> and condiciones sobre campos de E

Gracias de todas formas.
Pau.


"Alejandro Mesa" escribió en el
mensaje news:
> Pau Domínguez,
>
> Me parece, segun lo que comentastes, que debes usar "left join" en vez de
> "right join".
>
> ...
> right outer join B on A.FK3 = B.FK1
> right outer join E on b.FK2 = E.PK
> ...
>
>
> AMB
>
> "Pau Domínguez" wrote:
>
>> Hola a todos.
>> Tengo un programa que ejecuta una consulta SQL con outer joins que no
>> devuelve lo que se supone que debería.
>> El problema es el siguientes.
>> Tengo una consulta sobre 5 tablas llamemoslas A,B,C,D,E
>> A y B tienen una relacion maestro detalle pero hay registros en A sin
>> detalle en B.
>> Las demás tablas, son tablas maestras que contienen información sobre
>> campos
>> de A y B en concreto C y D sobre campos de A y E sobre campos de B.
>> Estas tres tablas están enlazadas con claves primarias y no hay problemas
>> de
>> integridad referencial en los datos.
>>
>> La consulta tiene que devolver todos los registros de A y cuando existan
>> registros detalle en B solo los que cumplan un filtro en la tabla E.
>>
>> En principio no parecía que tubiera que habler ningún problema la
>> sonsulta
>> sería algo así:
>> Select distinct a.*
>> from A inner join C on A.FK1 = C.PK
>> inner join D on A.FK2 = D.PK
>> right outer join B on A.FK3 = B.FK1
>> right outer join E on b.FK2 = E.PK
>> where condicion sobre campos de C
>> and condiciones sobre campos de E
>>
>> Pues bien, la consulta no devueve los mismos registros si aparacen las
>> condiciones sobre campos de E como si los omito.
>> (Las condiciones sobre E incluyen un "or e.campo is null"). Aunque según
>> entiendo yo, el right outer join obliga a devolver todos los registro de
>> la
>> tabla A
>> independientemente de los filtros sobre las tablas de la izquierda, cosa
>> que
>> no está pasando.
>>
>> Parece ser que cuando todos los registros detalle que exiten en B no
>> cumplen
>> el filtro no se muestra tampoco el registro de A.
>> ¿No va esto en contra de lo que se supone que hace el OUTER JOIN?
>>
>> Gracias.
>>
>> Pau.
>>
>>
>>
>>



Respuesta Responder a este mensaje
#4 rigo
21/11/2005 - 19:22 | Informe spam
Vamos a ver si entendi el problema:
1A y B tienen una relacion maestro detalle pero hay registros en A
sin
detalle en B ( segun la consulta right outer join B on A.FK3 = B.FK1 =>
La tabla A esta relaciona con B por los campos FK3 y FK1
respectivamente).
2. ...en concreto C y D sobre campos de A y E sobre campos de B. Por
consiguiente debe existir una relacion entre B y E.
3. segun observe en la consulta solo quiere visualizar datos de A
(Select distinct a.* )

Yo haria dos query y uniria los resultado:
1. Los registros de A que no tengan detalle
2. los registros de A que tengan detalle en B solo los que cumplan un
filtro en la tabla E.

Es decir:
select A.*
from A
where FK3 not in (select FK1 from B)
UNION
select A.*
from A
where FK3 in ( select FK1
from B inner join E on B.FK2 = E.PK
where condicion sobre campo E)
Respuesta Responder a este mensaje
#5 Pau Domínguez
22/11/2005 - 12:54 | Informe spam
Gracias Alejandro.
Ya encontré la solución en el newsgroup en inglés.
Mi error estaba en que las condiciones sobre la tabla E que son las que
definen los registros válidos de B debo de ponerlas en la clausula JOIN en
vez de el la WHERE.
Las restriciones definidas en WHERE afectan al resultado devuelto por las
JOIN. Parece ser que el motor del SQL primero define el conjunto de filas
mediante las restricciones de las clausulas JOIN y después realiza un
segundo filtro aplicando las de WHERE.
En mi caso según las select erronea original

Select distinct a.*
from A inner join C on A.FK1 = C.PK
inner join D on A.FK2 = D.PK
left outer join B on A.FK3 = B.FK1
left outer join E on b.FK2 = E.PK
where condicion sobre campos de C
and condiciones sobre campos de E

Las clausulas join devuelven todas las filas de A pero algunas de ellas
relacionadas con filas de B que cumplen NO cumplen las condiciones sobre los
campos de E. Al aplicar la clausula WHERE estas desaparecen. Con lo que en
el resultado no están todas las filas de A que yo esperaba.

La select correcta.

Select distinct a.*
from A inner join C on A.FK1 = C.PK
inner join D on A.FK2 = D.PK
left outer join B on A.FK3 = B.FK1
left outer join E on b.FK2 = E.PK and condiciones sobre campos
de E
where condicion sobre campos de C

En este otro caso las clausulas join devuelven todas las filas de A y
algunas de ellas relacionadas con filas de B pero solo las que cumplen las
condiciones sobre los campos de E. Las que en la primera select desaparecian
al aplicar el WHERE aquí permanecerían con las columnas de B a null si se
listaran en la clausula WHERE.

Nunca te acostarás sin saber una cosa más.
Pau.


"Alejandro Mesa" escribió en el
mensaje news:
Pau,

Para poder reproducir el problema, poder analizarlo y poder recomendar
algo,
creo que sera mejor si te armas un script con la definicion de las tablas,
unas filas de ejemplo y cual seria el resultado esperado. Como haz de
saber,
es casi imposible recomendar algo si no tenemos idea de lo que puede estar
pasando.


AMB

"Pau Domínguez" wrote:

Perdonad.
La consulta la tengo con LEFT OUTER JOIN no con right outer join como os
he
puesto.
He hecho tantas pruebas que se me ha ido el santo al cielo.

>> Select distinct a.*
>> from A inner join C on A.FK1 = C.PK
>> inner join D on A.FK2 = D.PK
>> LEFT outer join B on A.FK3 = B.FK1
>> LEFT outer join E on b.FK2 = E.PK
>> where condicion sobre campos de C
>> and condiciones sobre campos de E

Gracias de todas formas.
Pau.


"Alejandro Mesa" escribió en el
mensaje news:
> Pau Domínguez,
>
> Me parece, segun lo que comentastes, que debes usar "left join" en vez
> de
> "right join".
>
> ...
> right outer join B on A.FK3 = B.FK1
> right outer join E on b.FK2 = E.PK
> ...
>
>
> AMB
>
> "Pau Domínguez" wrote:
>
>> Hola a todos.
>> Tengo un programa que ejecuta una consulta SQL con outer joins que no
>> devuelve lo que se supone que debería.
>> El problema es el siguientes.
>> Tengo una consulta sobre 5 tablas llamemoslas A,B,C,D,E
>> A y B tienen una relacion maestro detalle pero hay registros en A sin
>> detalle en B.
>> Las demás tablas, son tablas maestras que contienen información sobre
>> campos
>> de A y B en concreto C y D sobre campos de A y E sobre campos de B.
>> Estas tres tablas están enlazadas con claves primarias y no hay
>> problemas
>> de
>> integridad referencial en los datos.
>>
>> La consulta tiene que devolver todos los registros de A y cuando
>> existan
>> registros detalle en B solo los que cumplan un filtro en la tabla E.
>>
>> En principio no parecía que tubiera que habler ningún problema la
>> sonsulta
>> sería algo así:
>> Select distinct a.*
>> from A inner join C on A.FK1 = C.PK
>> inner join D on A.FK2 = D.PK
>> right outer join B on A.FK3 = B.FK1
>> right outer join E on b.FK2 = E.PK
>> where condicion sobre campos de C
>> and condiciones sobre campos de E
>>
>> Pues bien, la consulta no devueve los mismos registros si aparacen las
>> condiciones sobre campos de E como si los omito.
>> (Las condiciones sobre E incluyen un "or e.campo is null"). Aunque
>> según
>> entiendo yo, el right outer join obliga a devolver todos los registro
>> de
>> la
>> tabla A
>> independientemente de los filtros sobre las tablas de la izquierda,
>> cosa
>> que
>> no está pasando.
>>
>> Parece ser que cuando todos los registros detalle que exiten en B no
>> cumplen
>> el filtro no se muestra tampoco el registro de A.
>> ¿No va esto en contra de lo que se supone que hace el OUTER JOIN?
>>
>> Gracias.
>>
>> Pau.
>>
>>
>>
>>



Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaSiguiente Respuesta Tengo una respuesta
Search Busqueda sugerida