none
no respeta LEFT JOIN RRS feed

  • Pregunta

  • SQL 2012    

    Consulta de existencias de artículos en tres bases diferentes.

    La base 1 tiene los 57 artículos que requerimos su existencia, pero la base 2 solo hay 46 y en la base 3 hay 50.

    dentro del WHERE se especifica el listado de los 57 artículos, existe una diferencia en la denominación del almacén de donde debe tomar las existencias ya que para 2 y 3 es GENERAL y para 1 es 01 este campo esta denominado como WhsCode.

    al ejecutar la sentencia solo muestra solo 40 artículos con las existencias correctas, si  retiro del WHERE los almacenes de 2 y 3 si muestra los 57 artículos pero las existencias  son incorrectas.

    esta es la sentencia:

            

    SELECT T0.[ItemCode], 
           T0.[ItemName],
       SUM (T1.[OnHand]-T1.[Iscommited]) as 1,
       SUM (T3.[OnHand]-T3.[Iscommited]) as 2,
           SUM (T5.[OnHand]-T5.[Iscommited]) as 3

    FROM

    1.dbo.OITM T0 left JOIN 1.dbo.OITW T1 ON T0.[ItemCode] = T1.[ItemCode] left JOIN 2.dbo.OITM T2 ON T2.[ItemCode] = T0.ItemCode left JOIN 2.dbo.OITW T3 ON T3.[ItemCode] = T2.[ItemCode] LEFT JOIN 3.dbo.OITM T4 ON T4.[ItemCode] = T0.ItemCode  LEFT JOIN 3.dbo.OITW T5 ON T5.[ItemCode] = T4.[ItemCode] 

    WHERE 

     T1.[WhsCode] = '01' and T3.[WhsCode] = 'GENERAL' and T5.[WhsCode] = 'GENERAL' and T0.ItemCode IN ('LHR-81-A', 'LHR-81-AC', 'MC11PA', 'ED0002A', 'W4AC-42-AC', 'LE-61-AC', '0SA00MCR', '01-0686988-06', 'MBE-4A-A', 'IONSMA', '1510A', 'L4DE-41-AC', 'VTX609F', 'IONF', '2015LPA', 'L53AP', 'IONSV3A', 'TAL65', 'TA9MD6L', '2015LPAM', '810CAAAR', 'VTC3A', '70F000AR', 'RSA03ZCR', 'BLD-12-A', 'L22LAP', 'LE-36-AA', 'IONV3A', 'AVC21AC', 'LHA-41-AC', 'LHR-81-35-A', 'VTX609A', 'MCRNSCF', 'LINSV2A', 'LINZ6F', 'MC16MA', '5GA00FAR', 'L41AM', 'L51AM', 'MCRNSCA', '70A02FAR', 'LED200A', 'MC23MA', 'R316AM', 'TADF8', 'L53AM', '5813A', 'LHS-62-AC', 'I3MC', 'I3KC', 'BMD-12-MP-A', 'L4E-42-A', 'R2LPHPA', 'R10HDMA', 'R316AF', 'R416AM', 'TBD2102') 

    GROUP BY T0.ItemCode,
           T0.ItemName 

    la cual da el siguiente resultado:

    Articulo   1    2    3                  sin los almacenes 2 y 3 :                    Articulo         1        2        3          

    1            10   0    0                                                                               1             90      0        0

    2             2    0   71                                                                              2             18       2      71

    3              0   0    32                                                                             3              0         1     32

    40           70   0    0                                                                              40            36        0      0

                                                                                                                57           630      0       0

    gracias por su ayuda.


    • Editado Arturo1137 miércoles, 31 de octubre de 2018 16:09
    miércoles, 31 de octubre de 2018 1:52

Respuestas

  • Dejame explicar primero que significa hacer LEFT OUTER JOIN y como este query ha transformado un LOJ a un INNER JOIN.

    Cuando hacemos un LOJ estamos indicando que se desea preservar la tabla a la izquierda (seleccionar todas las filas de esta tabla que cumplan el predicado en la clausula WHERE siempre y cuando el predicado solo incluya columnas de esta o de otra tabla que se una a esta mediante INNER JOIN).  Para las columnas referenciadas de la tabla del lado derecho se mostraran sus valores en caso de que exista una fila que cumpla la union o NULL en caso contrario.

    Ejemplo:

    T1(col1) : 1, 2, 3
    T2(col1) : 2, 3, 4

    T1 LOJ T2 on T2.col1 = T1.col1

    T1.col1  T2.col1
    1           NULL
    2           2
    3           3

    Si referenciamos una columna del lado derecho en la clausula WHERE (como en tu caso "T3.[WhsCode] = 'general' and T5.[WhsCode] = 'general'"), entonces para las filas del lado izquierdo que no tengan una fila correspondiente en el lado derecho el predicado seria similar a:

    NULL = 'general' and NULL = 'general'

    y como sabemos, la marca NULL no se puede comparar de esa forma y el predicado seria no conocido (unknown).  De esta forma has convertido el LOJ a un INNER JOIN.

    T1 LOJ T2 on T2.col1 = T1.col1
    WHERE T2.col1 = 3;

    es equivalente a:

    T1 INNER JOIN T2 on T2.col1 = T1.col1
    WHERE T2.col1 = 3;

    Si deseas que el predicado en la clausula WHERE sea considerado por el JOIN entonces debes promover este hacia la union:

    T1 LOJ T2 on T2.col1 = T1.col1 and T2.col1 = 3;

    T1.col1  T2.col1
    1           NULL
    2           NULL
    3           3

    o en tu caso:

    LEFT JOIN 2.dbo.OITM T2 ON T2.[ItemCode] = T0.ItemCode LEFT JOIN 2.dbo.OITW T3 ON T3.[ItemCode] = T2.[ItemCode] and T3.[WhsCode] = 'general' LEFT JOIN 3.dbo.OITM T4 ON T4.[ItemCode] = T0.ItemCode  LEFT JOIN 3.dbo.OITW T5 ON T5.[ItemCode] = T4.[ItemCode]  and T5.[WhsCode] = 'general'


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    • Editado HunchbackMVP miércoles, 31 de octubre de 2018 12:55
    • Marcado como respuesta Arturo1137 miércoles, 31 de octubre de 2018 16:06
    miércoles, 31 de octubre de 2018 12:49
  • Si te refieres a este orden:

    T0.ItemCode IN ('LHR-81-A', 'LHR-81-AC', 'MC11PA', 'ED0002A', 'W4AC-42-AC', 'LE-61-AC', '0SA00MCR', '01-0686988-06', 'MBE-4A-A', 'IONSMA', '1510A', 'L4DE-41-AC', 'VTX609F', 'IONF', '2015LPA', 'L53AP', 'IONSV3A', 'TAL65', 'TA9MD6L', '2015LPAM', '810CAAAR', 'VTC3A', '70F000AR', 'RSA03ZCR', 'BLD-12-A', 'L22LAP', 'LE-36-AA', 'IONV3A', 'AVC21AC', 'LHA-41-AC', 'LHR-81-35-A', 'VTX609A', 'MCRNSCF', 'LINSV2A', 'LINZ6F', 'MC16MA', '5GA00FAR', 'L41AM', 'L51AM', 'MCRNSCA', '70A02FAR', 'LED200A', 'MC23MA', 'R316AM', 'TADF8', 'L53AM', '5813A', 'LHS-62-AC', 'I3MC', 'I3KC', 'BMD-12-MP-A', 'L4E-42-A', 'R2LPHPA', 'R10HDMA', 'R316AF', 'R416AM', 'TBD2102') 

    entonces usa una expresion CASE en la clausula ORDER BY.

    ...
    ORDER BY
        case 
    T0.ItemCode
        when 
    'LHR-81-A' then 1
        ...
        when 
     'TBD2102' then ...
        end;


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    • Marcado como respuesta Arturo1137 miércoles, 31 de octubre de 2018 18:11
    miércoles, 31 de octubre de 2018 17:00

Todas las respuestas

  • Hola Arturo1137:

    es raro que T2 delenda de item0 y sin embargo t3 no. Lo mismo que t5.

    Ademas si t2 es nulo, t3 por tanto tambien luego no se dara la condicion del where t3.wswhere sera null

    Estan bien planteadas esas relaciones? Es un poco complicado ver el problema sino cuentas ni el escenario, ni el objetivo, ni los datos

    miércoles, 31 de octubre de 2018 6:00
  • Dejame explicar primero que significa hacer LEFT OUTER JOIN y como este query ha transformado un LOJ a un INNER JOIN.

    Cuando hacemos un LOJ estamos indicando que se desea preservar la tabla a la izquierda (seleccionar todas las filas de esta tabla que cumplan el predicado en la clausula WHERE siempre y cuando el predicado solo incluya columnas de esta o de otra tabla que se una a esta mediante INNER JOIN).  Para las columnas referenciadas de la tabla del lado derecho se mostraran sus valores en caso de que exista una fila que cumpla la union o NULL en caso contrario.

    Ejemplo:

    T1(col1) : 1, 2, 3
    T2(col1) : 2, 3, 4

    T1 LOJ T2 on T2.col1 = T1.col1

    T1.col1  T2.col1
    1           NULL
    2           2
    3           3

    Si referenciamos una columna del lado derecho en la clausula WHERE (como en tu caso "T3.[WhsCode] = 'general' and T5.[WhsCode] = 'general'"), entonces para las filas del lado izquierdo que no tengan una fila correspondiente en el lado derecho el predicado seria similar a:

    NULL = 'general' and NULL = 'general'

    y como sabemos, la marca NULL no se puede comparar de esa forma y el predicado seria no conocido (unknown).  De esta forma has convertido el LOJ a un INNER JOIN.

    T1 LOJ T2 on T2.col1 = T1.col1
    WHERE T2.col1 = 3;

    es equivalente a:

    T1 INNER JOIN T2 on T2.col1 = T1.col1
    WHERE T2.col1 = 3;

    Si deseas que el predicado en la clausula WHERE sea considerado por el JOIN entonces debes promover este hacia la union:

    T1 LOJ T2 on T2.col1 = T1.col1 and T2.col1 = 3;

    T1.col1  T2.col1
    1           NULL
    2           NULL
    3           3

    o en tu caso:

    LEFT JOIN 2.dbo.OITM T2 ON T2.[ItemCode] = T0.ItemCode LEFT JOIN 2.dbo.OITW T3 ON T3.[ItemCode] = T2.[ItemCode] and T3.[WhsCode] = 'general' LEFT JOIN 3.dbo.OITM T4 ON T4.[ItemCode] = T0.ItemCode  LEFT JOIN 3.dbo.OITW T5 ON T5.[ItemCode] = T4.[ItemCode]  and T5.[WhsCode] = 'general'


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    • Editado HunchbackMVP miércoles, 31 de octubre de 2018 12:55
    • Marcado como respuesta Arturo1137 miércoles, 31 de octubre de 2018 16:06
    miércoles, 31 de octubre de 2018 12:49
  • Muchas gracias así funciono, dio las existencias correctas y todos los artículos.

    hay forma de que el resultado se muestre el orden de los artículos como los tengo en el WHERE?

    miércoles, 31 de octubre de 2018 16:08
  • Si te refieres a este orden:

    T0.ItemCode IN ('LHR-81-A', 'LHR-81-AC', 'MC11PA', 'ED0002A', 'W4AC-42-AC', 'LE-61-AC', '0SA00MCR', '01-0686988-06', 'MBE-4A-A', 'IONSMA', '1510A', 'L4DE-41-AC', 'VTX609F', 'IONF', '2015LPA', 'L53AP', 'IONSV3A', 'TAL65', 'TA9MD6L', '2015LPAM', '810CAAAR', 'VTC3A', '70F000AR', 'RSA03ZCR', 'BLD-12-A', 'L22LAP', 'LE-36-AA', 'IONV3A', 'AVC21AC', 'LHA-41-AC', 'LHR-81-35-A', 'VTX609A', 'MCRNSCF', 'LINSV2A', 'LINZ6F', 'MC16MA', '5GA00FAR', 'L41AM', 'L51AM', 'MCRNSCA', '70A02FAR', 'LED200A', 'MC23MA', 'R316AM', 'TADF8', 'L53AM', '5813A', 'LHS-62-AC', 'I3MC', 'I3KC', 'BMD-12-MP-A', 'L4E-42-A', 'R2LPHPA', 'R10HDMA', 'R316AF', 'R416AM', 'TBD2102') 

    entonces usa una expresion CASE en la clausula ORDER BY.

    ...
    ORDER BY
        case 
    T0.ItemCode
        when 
    'LHR-81-A' then 1
        ...
        when 
     'TBD2102' then ...
        end;


    AMB

    Some guidelines for posting questions...

    AYÚDANOS A AYUDARTE, guía básica de consejos para formular preguntas

    • Marcado como respuesta Arturo1137 miércoles, 31 de octubre de 2018 18:11
    miércoles, 31 de octubre de 2018 17:00
  • gracias nuevamente
    miércoles, 31 de octubre de 2018 18:11