none
Datos duplicados en dos inner join RRS feed

  • Pregunta

  • Buenos dias

    Esto es lo que pasa: Hago select a una tabla que solo me da un dato pongo inner join a tres tablas que dos dan 10 resultados y la otra da un resultado, el problema es que pone todo el resultado del segundo inner join en un resultado del primer inner join.

    Asi queda el resultado:

    NUMERO - PEDIMENTO - CAJA

    NU06     -  7001234     - AA12

    NU06     -  7001234     - AA13

    NU06     -  7001234     - AA14

    NU07     -  7001234     - AA12

    NU07     -  7001234     - AA13

    NU07     -  7001234     - AA14

    NU08     -  7001234     - AA12

    NU08     -  7001234     - AA13

    NU08     -  7001234     - AA14

    Quiero que quede asi:

    NUMERO - PEDIMENTO - CAJA

    NU06     -  7001234     - AA12

    NU07     -  7001234     - AA13

    NU08     -  7001234     - AA14

    Asi es el query:

    select 
    pf.Numero
    , p.Pedimento
    , pc.Numero as Caja
    
    from vt_pedimentos p
    
    inner join vt_pedimentocontened pc on pc.Pedimento = p.ID
    inner join vt_clientes cl on cl.ID = p.Cliente 
    	and cl.Numero = 'CCOBREGON'
    inner join vt_PedimentoFacturas pf on pf.Pedimento = p.ID
    
    where p.FechaDePago >= '2017-08-01' and p.FechaDePago <= '2017-08-16'
    
    order by Pedimento, Numero, Caja

    • Tipo cambiado Moderador M viernes, 1 de septiembre de 2017 18:50
    jueves, 31 de agosto de 2017 17:26

Respuestas

  • Buenas, te aconsejo hacer las uniones "join" por los campos llaves y luego utilizar agrupaciones o un distinct.  Te va repetir el ID contacto gracias a los joins que hagas, si utilizas algo como ejemplo:

    SELECT C.IDCONTACTO, ISNULL(T.TELEFONO,'') TELEFONO, ISNULL( E.CORREO,'')
    FROM CONTACTOS C WITH(NOLOCK)
    LEFT JOIN TELEFONOS T WITH(NOLOCK) ON
    C.IDCONTACTO = T.IDCONTACTO
    LEFT JOIN CORREOS E WITH(NOLOCK) ON
    C.IDCONTACTO = E.IDCONTACTO
    GROUP BY C.IDCONTACTO, T.TELEFONO, E.CORREO

    Si lo que necesitas es obtener un único correo y un único teléfono por contacto  deberías usar un MAX por cada tabla, por ejemplo:

    SELECT C.IDCONTACTO, ISNULL(T1.TELEFONO,'') TELEFONO, ISNULL( E1.CORREO,'') CORREO
    FROM CONTACTOS C WITH(NOLOCK)
    LEFT JOIN (
    SELECT T.IDCONTACTO, MAX(T.TELEFONO) FROM TELEFONOS T WITH(NOLOCK) GROUP BY T.IDCONTACTO
    ) AS T1 ON 
    C.IDCONTACTO = T1.IDCONTACTO
    LEFT JOIN (
    SELECT E.IDCONTACTO, E.CORREO FROM  CORREOS E WITH(NOLOCK) GROUP BY E.IDCONTACTO
    ) AS E1 ON
    C.IDCONTACTO = E1.IDCONTACTO
    GROUP BY C.IDCONTACTO, T1.TELEFONO, E1.CORREO

    Traer la información depende de lo que necesites y las consultas de ejemplo son solo una forma de hacer las cosas, se puede optimizar y hacerse de otras maneras.

    Espero que te sirva . Saludos.

    • Propuesto como respuesta Moderador M viernes, 1 de septiembre de 2017 18:50
    • Marcado como respuesta Moderador M martes, 5 de septiembre de 2017 15:55
    jueves, 31 de agosto de 2017 19:39

Todas las respuestas

  • Cuando haces varios join en una sentencia SQL, se ejecutan todos juntos, y te devuelve todas las posibles combinaciones que satisfagan las cláusulas ON. Eso implica que si por ejemplo, un registro de una tabla se empareja con dos de otra, eso hace que salgan dos veces los datos del registro de la primera. Y si esos dos a su vez emparejan cada uno de ellos con tres datos de una tercera tabla, saldrían 6 registros en total, con todas las repeticiones que les correspondan. El orden de los joins no es significativo, siempre se forman todas las combinaciones posibles con independencia de cuál sea la pareja de tablas que las genera.
    jueves, 31 de agosto de 2017 17:34
  • Cuando haces varios join en una sentencia SQL, se ejecutan todos juntos, y te devuelve todas las posibles combinaciones que satisfagan las cláusulas ON. Eso implica que si por ejemplo, un registro de una tabla se empareja con dos de otra, eso hace que salgan dos veces los datos del registro de la primera. Y si esos dos a su vez emparejan cada uno de ellos con tres datos de una tercera tabla, saldrían 6 registros en total, con todas las repeticiones que les correspondan. El orden de los joins no es significativo, siempre se forman todas las combinaciones posibles con independencia de cuál sea la pareja de tablas que las genera.
    y hay alguna forma de hacer lo que quiero ?
    jueves, 31 de agosto de 2017 17:42
  • Bueno, no veo muy claro lo que quieres (porque requiere conocer los requisitos y la estructura de tablas), pero si el problema básico es que en el join se están uniendo varios registros de una tabla cuando solo se deseaba unir uno de ellos, entonces la solución puede ser usar una subconsulta escalar en la lista de selección. Es decir, algo así:

    Select tabla1.Campo1, tabla2.Campo2, (select TOP 1 campo3 from tabla3 where tabla1.codigo=tabla3.Codigo), ... FROM ...

    jueves, 31 de agosto de 2017 18:04
  • Bueno, no veo muy claro lo que quieres (porque requiere conocer los requisitos y la estructura de tablas), pero si el problema básico es que en el join se están uniendo varios registros de una tabla cuando solo se deseaba unir uno de ellos, entonces la solución puede ser usar una subconsulta escalar en la lista de selección. Es decir, algo así:

    Select tabla1.Campo1, tabla2.Campo2, (select TOP 1 campo3 from tabla3 where tabla1.codigo=tabla3.Codigo), ... FROM ...

    El problema es que las dos tablas, la de Numero y Caja tienen 10 resultados con el mismo Pedimento, y ocupo traer esas dos tablas con todos sus campos relacionados con el Pedimento y que no se repita el Numero ni la Caja
    jueves, 31 de agosto de 2017 18:11
  • Es difícil dar una respuesta segura sin conocer exactamente cómo son tus datos. Podrías hacer un "select distinct" sobre el join de esas tablas cuyos registros no quieres repetir, y después al resultado de ese select hacerle el join contra el resto de las tablas.
    jueves, 31 de agosto de 2017 18:25
  • Es difícil dar una respuesta segura sin conocer exactamente cómo son tus datos. Podrías hacer un "select distinct" sobre el join de esas tablas cuyos registros no quieres repetir, y después al resultado de ese select hacerle el join contra el resto de las tablas.

    Talves no me explique bien, estos son los datos por tabla:

    vt_PedimentoFacturas:

    Numero - Pedimento

    NU06     - 7001234

    NU07     - 7001234

    NU08     - 7001234

    NU09     - 7001235

    NU010   - 7001235

    vt_pedimentocontened:

    Caja  - Pedimento

    AA12 - 7001234

    AA13 - 7001234

    AA14 - 7001234

    AA15 - 7001235

    AA16 - 7001235

    vt_pedimentos:

    ID - Pedimento

    14 - 7001234

    15 - 7001235

    16 - 7001236

    Quiero obtener todos los datos de las 3 que tengan como Pedimento = 7001234, solo que al hacer inner join a vt_PedimentoFacturas y vt_pedimentocontened pone los siguientes datos:

    NUMERO - PEDIMENTO - CAJA

    NU06     -  7001234     - AA12

    NU06     -  7001234     - AA13

    NU06     -  7001234     - AA14

    NU07     -  7001234     - AA12

    NU07     -  7001234     - AA13

    NU07     -  7001234     - AA14

    NU08     -  7001234     - AA12

    NU08     -  7001234     - AA13

    NU08     -  7001234     - AA14

    Y lo quiero de esta forma:

    NUMERO - PEDIMENTO - CAJA

    NU06     -  7001234     - AA12

    NU07     -  7001234     - AA13

    NU08     -  7001234     - AA14


    • Editado luisz15 jueves, 31 de agosto de 2017 18:42 Me equivoque
    jueves, 31 de agosto de 2017 18:41
  • Buenas, te aconsejo hacer las uniones "join" por los campos llaves y luego utilizar agrupaciones o un distinct.  Te va repetir el ID contacto gracias a los joins que hagas, si utilizas algo como ejemplo:

    SELECT C.IDCONTACTO, ISNULL(T.TELEFONO,'') TELEFONO, ISNULL( E.CORREO,'')
    FROM CONTACTOS C WITH(NOLOCK)
    LEFT JOIN TELEFONOS T WITH(NOLOCK) ON
    C.IDCONTACTO = T.IDCONTACTO
    LEFT JOIN CORREOS E WITH(NOLOCK) ON
    C.IDCONTACTO = E.IDCONTACTO
    GROUP BY C.IDCONTACTO, T.TELEFONO, E.CORREO

    Si lo que necesitas es obtener un único correo y un único teléfono por contacto  deberías usar un MAX por cada tabla, por ejemplo:

    SELECT C.IDCONTACTO, ISNULL(T1.TELEFONO,'') TELEFONO, ISNULL( E1.CORREO,'') CORREO
    FROM CONTACTOS C WITH(NOLOCK)
    LEFT JOIN (
    SELECT T.IDCONTACTO, MAX(T.TELEFONO) FROM TELEFONOS T WITH(NOLOCK) GROUP BY T.IDCONTACTO
    ) AS T1 ON 
    C.IDCONTACTO = T1.IDCONTACTO
    LEFT JOIN (
    SELECT E.IDCONTACTO, E.CORREO FROM  CORREOS E WITH(NOLOCK) GROUP BY E.IDCONTACTO
    ) AS E1 ON
    C.IDCONTACTO = E1.IDCONTACTO
    GROUP BY C.IDCONTACTO, T1.TELEFONO, E1.CORREO

    Traer la información depende de lo que necesites y las consultas de ejemplo son solo una forma de hacer las cosas, se puede optimizar y hacerse de otras maneras.

    Espero que te sirva . Saludos.

    • Propuesto como respuesta Moderador M viernes, 1 de septiembre de 2017 18:50
    • Marcado como respuesta Moderador M martes, 5 de septiembre de 2017 15:55
    jueves, 31 de agosto de 2017 19:39
  • llego tarde bro, apenas estoy aprendiendo SQL y me sucedió lo mismo, así que esta es una opción a tu respuesta del 2017 

    R= usa DISTINCT 

    SELECT DISNTINCT (..........)

    jueves, 15 de abril de 2021 2:54