Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > MS SQL Server
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 03-11-2005
Avatar de Cabanyaler
Cabanyaler Cabanyaler is offline
Miembro
 
Registrado: jun 2003
Ubicación: País Valencià
Posts: 339
Poder: 21
Cabanyaler Va por buen camino
LEFT INNER JOIN & RIGHT INNER JOIN

Hola, veamos.
Tengo un problema que se me está agrandando por motivos del normalizado de la BBDD y de la gran cantidad de filtros o campos por los que puede y desea consultar el usuario.
Expongo de manera resumidísima:Quiero hacer una consulta sobre dos tablas donde cada una de ellas posee sus claves principales y la esclava con su clave ajena refrenciando a la principal. (hasta aquí todo normal).
Una de las consultas posibles es:

SELECT A.*
FROM A
LEFT OUTER JOIN B
ON B.CAjena = A.CPrincipal


ok!, esto debería devolver todas las tuplas que existen en A independientemente de valores, ya que no establezco clausula WHERE. Pero me retorna sólo todas las tuplas de A que tienen relación con alguna tupla de B.

Mi deseo es obtener todas las tuplas de A, tengan o no tengan tuplas relacionadas en B.

Obviamente he resumido la consulta, ya que para eso haría SELECT * FROM A, pero lo que deseo es poder consultar tablas relacionadas con el INNER JOIN y que me retorne todas las de la maestra que cumplan los filtros establecidos sobre las tuplas esclavas y ademas las tuplas de la maestra que NO TENGAN ninguna tupla relacionada en la esclava.

Espero haberlo expuesto de forma entendible.
Gracias por vuestra ayuda y un saludo.
__________________
El meu país és tan petit, que des de dalt d'un campanar es pot veure el campanar veí.
Responder Con Cita
  #2  
Antiguo 03-11-2005
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por Cabanyaler
Una de las consultas posibles es:
SELECT A.*
FROM A
LEFT OUTER JOIN B
ON B.CAjena = A.CPrincipal

ok!, esto debería devolver todas las tuplas que existen en A independientemente de valores, ya que no establezco clausula WHERE. Pero me retorna sólo todas las tuplas de A que tienen relación con alguna tupla de B.
Eso devuelve todas las tuplas de A tengan o no relación con B.
Si no es así es porque se eliminan por otro sitio, pruebalo con dos tablas simples y verás como sí (supongo que al resumir la consulta te has dejado alguna cosa importante).


Cita:
Empezado por Cabanyaler
Mi deseo es obtener todas las tuplas de A, tengan o no tengan tuplas relacionadas en B.
Para eso justo está el LEFT JOIN.

Cita:
Empezado por Cabanyaler
...pero lo que deseo es poder consultar tablas relacionadas con el INNER JOIN y que me retorne todas las de la maestra que cumplan los filtros establecidos sobre las tuplas esclavas y ademas las tuplas de la maestra que NO TENGAN ninguna tupla relacionada en la esclava.
Lo uno contradice lo otro. INNER JOIN te devolverá sólo las tuplas que existan en ambas tablas por definición.
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #3  
Antiguo 03-11-2005
Avatar de Cabanyaler
Cabanyaler Cabanyaler is offline
Miembro
 
Registrado: jun 2003
Ubicación: País Valencià
Posts: 339
Poder: 21
Cabanyaler Va por buen camino
Lo primero gracias.

Sí, eso entiendo que es el resultado del LEFT INNER JOIN, pero sin resumir la consulta y a falta de las declaraciones de los parametros, expongo la consulta completa:
Código SQL [-]
SELECT 
   Contratos.*

FROM
   Contratos

   /* Uno por C.Aj con Clientes y estos con TelefonosCli*/
   LEFT OUTER JOIN
   Clientes LEFT OUTER JOIN TelefonosCli     
                         ON TelefonosCli.CodCli_TelCli = Clientes.CodAut_Cli
   ON Clientes.CodAut_Cli = Contratos.CodCli_Con

WHERE  
   ( 
   (   (Contratos.NumCon_Con LIKE '%' + @NumCon_sp + '%' )
   AND (Contratos.FecCon_Con >= @FecIniCon_sp  AND Contratos.FecCon_Con <= @FecFinCon_sp)
   AND (Contratos.FecEnt_Con >= @FecIniEnt_sp  AND Contratos.FecEnt_Con <= @FecFinEnt_sp)
   AND (Contratos.TipCon_Con   LIKE '%' + @TipCon_sp + '%')
   AND (Contratos.ExeCon_Con  = @ExeCon_sp)
   AND (Contratos.MotExe_Con   LIKE '%' + @MotExe_sp + '%')
   AND (Contratos.Obs2Con_Con LIKE '%' + @Obs2Con_sp + '%')
   AND (Contratos.DesPro_Con    LIKE '%' + @DesPro_sp + '%')
   AND (Contratos.FecAvi_Con >= @FecIniAvi_sp  AND Contratos.FecAvi_Con <= @FecFinAvi_sp)
   AND (Contratos.TotCon_Con >= @TotConIni_sp AND Contratos.TotCon_Con  <= @TotConFin_sp)
   AND (Contratos.EntCeg_Con   = @EntCeg_sp)
   AND (Contratos.EntDis_Con    = @EntDis_sp)
   AND ((Contratos.ObsCon_Con  LIKE '%' + @ObsCon_sp + '%') OR (Contratos.ObsCon_Con IS NULL))
   )

 AND

         ((Clientes.TipVia_Cli  LIKE '%' + @TipVia_sp + '%')   /* Tots els Clientes que pasen els filtres amb determinat TelefonoCli*/
      AND (Clientes.DirCli_Cli  LIKE '%' + @DirCli_sp + '%') 
      AND (Clientes.NumPto_Cli  LIKE '%' + @NumPto_sp + '%') 
      AND (Clientes.NumPta_Cli  LIKE '%' + @NumPta_sp + '%') 
      AND (Clientes.EscCli_Cli  LIKE '%' + @EscCli_sp + '%') 
      AND (Clientes.NomCli_Cli  LIKE '%' + @NomCli_sp + '%') 
      AND (Clientes.DniCli_Cli  LIKE '%' + @DniCli_sp + '%') 
      AND (Clientes.LetCif_Cli  LIKE '%' + @LetCif_sp + '%') 
      AND (Clientes.PobCli_Cli  LIKE '%' + @PobCli_sp + '%') 
      AND (Clientes.CodPos_Cli  LIKE '%' + @CodPos_sp + '%') 
      AND (Clientes.RefCli_Cli  LIKE '%' + @RefCli_sp + '%') 
      AND (Clientes.CodCli_Cli  LIKE '%' + @CodCli_sp + '%')) 
      AND TelefonosCli.NumTel_telCli LIKE '%' + @NumTel_sp + '%' 
)

ORDER BY Contratos.TipCon_Con

Esto debería retornar todas las tuplas de la tabla Contratos que cumplen las condiciones del WHERE propias de los Contratos además de que las tuplas del Cliente asociado que cumplan tambien las condiciones del WHERE de los Clientes y el telefono del cliente tambien pase el filtro . Además de todos los Contratos que por estar unidos por el LEFT INNER JOIN no tengan o bien clientes o clientes sin telefono.

¿NO? Créeme, ójala esté equivocado!!
__________________
El meu país és tan petit, que des de dalt d'un campanar es pot veure el campanar veí.

Última edición por vtdeleon fecha: 04-11-2005 a las 12:09:15. Razón: Etiqueta SQL
Responder Con Cita
  #4  
Antiguo 03-11-2005
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.275
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por Cabanyaler
...Además de todos los Contratos que por estar unidos por el LEFT INNER JOIN no tengan o bien clientes o clientes sin telefono.
A éstos también se les aplica el filtro. ¿A ver si los nulos no te están pasando los filtros y ahí es donde se te quedan?
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #5  
Antiguo 03-11-2005
Avatar de Cabanyaler
Cabanyaler Cabanyaler is offline
Miembro
 
Registrado: jun 2003
Ubicación: País Valencià
Posts: 339
Poder: 21
Cabanyaler Va por buen camino
No, ufffff, no tengo valores nulos .Ya había valorado esta opción, aunque la he vuelto a considerar.

Lo único que me retorna (pasando todos los parametros vacios, menos el del Contratos.ExeCon_Con = @ExeCon_sp) son aquellos contratos que tienen clientes y que estos clientes tienen teléfono, en el caso de no tener teléfono, no los muestra.

Esto me está llevando a realizar diferentes consultas según los parametros que pase con valor además de que tablas necesite consultar, creciéndome exponencialmente las consultas a razón de las combinaciones de todas las tablas relacionadas con los contratos o alguna tabla esclava de estos.

Por ejemplo, si quiero que la consulta me retorne todos los contratos con cliente independientemente del número de teléfono, es decir, tenga teléfono con cualquier número o no tenga teléfono ese determinado cliente del contrato, escribo la misma consulta pero sin el INNER JOIN de relación con el contrato:

...
FROM
Contratos
LEFT OUTER JOIN
Clientes ON Clientes.CodAut_Cli = Contratos.CodCli_Con

en lugar de:
...
FROM
Contratos
LEFT OUTER JOIN
Clientes LEFT OUTER JOIN TelefonosCli
ON TelefonosCli.CodCli_TelCli = Clientes.CodAut_Cli
ON Clientes.CodAut_Cli = Contratos.CodCli_Con



En fin... No veas el lio y el curro combinacinal que tengo.
__________________
El meu país és tan petit, que des de dalt d'un campanar es pot veure el campanar veí.
Responder Con Cita
  #6  
Antiguo 03-11-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Que tal.

Veo un grave problema de concepto por aqui.

Estas mandando pedir todos los contratos, tengan o no cliente, pero luego filtras aquellos cuya dirección (del cliente) sea similar a x.

Si no hay cliente, ¿cómo su dirección podría ser similar a algo?

Otro asunto es la versión de sqlserver que estas utilizando, puesto que antes del 2000, si no mal recuerdo, el comportamiento con los filtros y los encuentros externos era erratico, pues el motor filtraría registros que si pasan por el where con que solo se referenciara la tabla externa en dicha clausula.

Lo dejaré hasta alli, pues no he leido toda la consulta, principalmente por no estar publicada con la etiqueta [ sql ], que facilitaría en mucho su rápida comprensión, y porque después de un par de años por aqui, me parece imprescindible que la uses.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #7  
Antiguo 04-11-2005
Avatar de Cabanyaler
Cabanyaler Cabanyaler is offline
Miembro
 
Registrado: jun 2003
Ubicación: País Valencià
Posts: 339
Poder: 21
Cabanyaler Va por buen camino
Hola, antes de nada agradecerte tu interés. Disculpa por no ponerlo como [code] o [sql], no conocía la etiqueta. Y no son dos años por aquí, son más lo que ocurre es que perdí la antiguedad al darme de alta de nuevo cuando cambió la página del foro.
Veamos.

Con respecto a lo que me comentas en tu observación:

Estas mandando pedir todos los contratos, tengan o no cliente, pero luego filtras aquellos cuya dirección (del cliente) sea similar a x.

Si no hay cliente, ¿cómo su dirección podría ser similar a algo?


Si es cierto que quiero todos los contratos, independientemente de si tiene cliente o si teniendo cliente independientemente de si este a su vez tiene teléfono etc. Pero, ¿de eso no se encarga precisamente el LEFT INNER JOIN?, de retornar todos los contratos tengan o no cliente o todos los clientes con contrato tengan o no teléfono, y si lo tienen aplicarles las clausulas WHERE?

Por cierto y retomando lo de las etiquetas, ¿como puedo incluir el texto coloreado en verde como una cita de tu anterior respuesta?.

Gracias a todos.
__________________
El meu país és tan petit, que des de dalt d'un campanar es pot veure el campanar veí.
Responder Con Cita
  #8  
Antiguo 04-11-2005
Avatar de __hector
[__hector] __hector is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Santo Domingo, Rep. Dom.
Posts: 1.075
Poder: 23
__hector Va por buen camino
Arriba Barςa!!
__________________
Héctor Geraldino
Software Engineer
Responder Con Cita
  #9  
Antiguo 04-11-2005
Avatar de lucasarts_18
lucasarts_18 lucasarts_18 is offline
Miembro
 
Registrado: mar 2005
Ubicación: Villa Alemana,Chile
Posts: 1.087
Poder: 21
lucasarts_18 Va por buen camino
Cita:
Empezado por Cabanyaler
Por cierto y retomando lo de las etiquetas, ¿como puedo incluir el texto coloreado en verde como una cita de tu anterior respuesta?.

Gracias a todos.
Al momento de responder tienes al lado derecho, en la parte inferior un botón llamado Citar...

O bien a traves de las etiquetas Quote.

Ejemplo
[quote=minombre].......[/QUOTE..

No he cerrado el último corchete o sino no me aparece nada, pero al momento de citar si debes hacerlo!!.

Hasta Luego -
__________________
No todo es como parece ser...
Responder Con Cita
  #10  
Antiguo 05-11-2005
Avatar de jachguate
jachguate jachguate is offline
Miembro
 
Registrado: may 2003
Ubicación: Guatemala
Posts: 6.254
Poder: 27
jachguate Va por buen camino
Cita:
Empezado por Cabanyaler
Si es cierto que quiero todos los contratos, independientemente de si tiene cliente o si teniendo cliente independientemente de si este a su vez tiene teléfono etc. Pero, ¿de eso no se encarga precisamente el LEFT INNER JOIN?, de retornar todos los contratos tengan o no cliente o todos los clientes con contrato tengan o no teléfono, y si lo tienen aplicarles las clausulas WHERE?
¿left inner join?. No lo creo. Será un left outer join .

Efectivamente, el left outer join se encarga de traer todos los contratos, independientemente de si tienen cliente o no. Podes comprobarlo quitando de la clausula where todo lo que haga referencia a campos de la tabla cliente o teléfono.

El problema se da precisamente cuando NO hay un cliente, pues tu clausula where se encarga de filtrar TODOS estos registros, pues no prevee ninguna condición que los deje pasar.

Dado que el left join devolverá null para todos los campos de la tabla cliente cuando no exista un registro asociado a esta, lo usual es incluir en el where los correspondientes "or's" para que deje "pasar" estos registros, algo como:
Código SQL [-]
select f.*, c.*
  from factura f
       left outer join cliente c on c.idcliente = f.id_cliente
 where (c.ciudad = 'GUATEMALA' OR c.ciudad is null)
   and (c.apellido like '%CASTILLO%' or c.apellido is null);

Esto devolverá todas las facturas para clientes con apellido CASTILLO de la ciudad de guatemala y todas aquellas que no tengan asociado un cliente.

Hasta luego.

__________________
Juan Antonio Castillo Hernández (jachguate)
Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate
Responder Con Cita
  #11  
Antiguo 07-11-2005
Avatar de Cabanyaler
Cabanyaler Cabanyaler is offline
Miembro
 
Registrado: jun 2003
Ubicación: País Valencià
Posts: 339
Poder: 21
Cabanyaler Va por buen camino
Hola, gracias por todo. Voy a probrarlo, pero no entiendo porque de :

Cita:
Empezado por jachguate
que el left join devolverá null para todos los campos de la tabla cliente cuando no exista un registro asociado a esta, lo usual es incluir en el where los correspondientes "or's" para que deje "pasar" estos registros,
pero si en realidad hace eso internamente, nadie somos nosotros pobres mortales para cuestionar el funcionamiento interno de la santa madre.

Ya digo en que he quedado.
__________________
El meu país és tan petit, que des de dalt d'un campanar es pot veure el campanar veí.
Responder Con Cita
  #12  
Antiguo 07-11-2005
Avatar de Cabanyaler
Cabanyaler Cabanyaler is offline
Miembro
 
Registrado: jun 2003
Ubicación: País Valencià
Posts: 339
Poder: 21
Cabanyaler Va por buen camino
Correcto.
Pero por la propia idiosincrasia de los resultados que busco aún así me veo obligado a la combinatoria de LEFT OUTER JOIN con unas tablas o no.
Gracias por vuestra ayuda, colaboración e interes.
Força.
__________________
El meu país és tan petit, que des de dalt d'un campanar es pot veure el campanar veí.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 07:44:10.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi