none
Resultado de consulta a tabla detalle incompleta - Totales no coincide con sumatoria del detalle RRS feed

  • Pregunta

  • Buenas tardes,

    Estoy utilizando SqlServer Express 2014. Cuando ejecuto el query mencionado abajo para listar el detalle de cada orden no obtiene la totalidad de los items o árticulos de la misma.

    Me percato que en el resultado del detalle que agrupa sin que yo lo condicione, los items iguales, Es decir si existen dos productos iguales en el detalle de una misma orden sólo me trae uno de ellos, por tanto la sumatoria del detalle nunca coincide con el total de cada orden. El query para obtener el detalle es este:                               

    SELECT 

    sla.[Document Type] 
    ,sla.[Document No_] AS 'Num'
    ,sha.[Order Date] AS 'Date'
    ,sha.[Sell-to Customer Name] AS 'Name'
    ,sla.[Version No_] 
    ,sha.[Salesperson Code] AS 'Rep'
    ,sla.[Quantity]
    ,sla.[Unit Price]
    ,sla.[Amount]
    ,sha.[Ship-to Address] AS 'Ship to'
    ,sha.[Ship-to County] AS 'State'
    ,sha.[Ship-to Post Code] AS 'ZipCode'
    ,sla.[No_] AS 'Sku'
    ,i.[Unit Price] AS 'Ipl' 
    ,sla.[Location Code]
    ,sha.[Payment Terms Code] AS 'Terms' 
    ,sla.[Product Group Code] AS 'Family'
    ,sla.[Item Category Code] 
    , CASE 
    WHEN sla.[Item Category Code]='ARMAMENT' THEN 'ARMAMENT'
    ELSE 'TAGUA'
     END AS 'Brand'
     FROM 
    [ZenUS].[dbo].[Zen Distributor Group LLC$Sales Line Archive] AS sla 
    ,[ZenUS].[dbo].[Zen Distributor Group LLC$Sales Header Archive] AS sha


     WHERE 
    sha.[No_]=sla.[Document No_]

     AND
    sha.[Sell-to Customer No_]=sla.[Sell-to Customer No_]

     AND
    sla.[Version No_]=sha.[Version No_]


     AND 
    sha.[Order Date] BETWEEN  CAST( CAST( @finicio AS DATE ) AS DATETIME ) AND CAST( CAST( @ffin AS DATE ) AS DATETIME )

     AND 
    sla.[Document Type]='1' /* Solo Sales Orders */ 


    viernes, 28 de abril de 2017 19:10

Todas las respuestas

  • Fíjate que en realidad lo que estás haciendo es un "inner join" de las dos tablas, solo que estás usando la sintaxis antigua de SQL-89 en lugar de la moderna de SQL-92 y por eso no se ve claro el JOIN. La condición de unión de las tablas está formada por tres campos distintos. Cuando al hacer esto no te salen todos los registros que tenían que salir, indica que la condición está mal puesta. Es decir, los campos que se han indicado o bien son excesivamente restrictivos y no representan la condición correcta de unión, o no representan correctamente una combinación unívoca, o contienen algunos valores que son NULL, o sucede alguna otra circunstancia análoga a las anteriores que hace que el join no arroje los resultados esperados.

    Lo ideal sería que las tablas estuvieran bien normalizadas y que conectaran mediante la clave primaria de la tabla madre y un foreign key en la tabla hija, y que se utilizase una clave surrogada en lugar de una clave natural. Pero si no es factible modificar las tablas, entonces hay que depurar el join. Hay que listar a mano los datos de una orden, primero en la tabla maestra y luego en la tabla de detalle, ponerlos en un papel lado a lado, y luego ir comparando uno por uno los valores de los campos que se enlazan en la sentencia SQL a ver si emparejan correctamente, hasta que se encuentre cuáles son los valores que no concuerdan. Llegados a ese punto, hay que analizar de qué campos se dispone y tomar una decisión acerca de cuáles son los que realmente se podrían usar para enlazar las dos tablas en la forma deseada.

    viernes, 28 de abril de 2017 20:00
  • Gracias por la pronta respuesta Alberto, pero aún modificando el Join  en el query, que detallo más abajo tengo el mismo inconveniente. He verificado la documentación de las tablas veo que los campos que utilizo son índices de las mismas y sus correspondientes Foreign keys.

    Según leí en algunos foros comentan que es un error del sql server con el tratamiento de fechas, pero también ya he utilizado otros métodos de consulta de fechas con el mismo resultado.

     Ahora, si listo el detalle de ordenes filtrando por número de orden en el query si,  lista el detalle completo. De allí que presumo que se trata de un Bug de fechas o algún metodo que este pasando por alto por desconocimiento en el formato de fechas del query.

    En la base de datos el campo [Order Date] que es el que utilizo para los filtros tiene este formato :aaaa-mm-dd hh:mi:ss.mmm

    DECLARE @finicio AS DATE; ; /*Variables Auxiliares fecha inicial Formato MM/DD/AA*/  
    DECLARE @ffin AS DATE; ; /*Variables Auxiliares fecha final Formato MM/DD/AA */
    SET @finicio = '2017/03/01';
    SET @ffin = '2017/03/31';


    SELECT 

    sla.[Document Type] 
    ,sla.[Document No_] AS 'Num'
    ,sha.[Order Date] AS 'Date'
    ,sha.[Sell-to Customer Name] AS 'Name'
    ,sla.[Version No_] 
    ,sha.[Salesperson Code] AS 'Rep'
    ,sla.[Quantity]
    ,sla.[Unit Price]
    ,sla.[Amount]
    ,sha.[Ship-to Address] AS 'Ship to'
    ,sha.[Ship-to County] AS 'State'
    ,sha.[Ship-to Post Code] AS 'ZipCode'
    ,sla.[No_] AS 'Sku'
    ,i.[Unit Price] AS 'Ipl' 
    ,sla.[Location Code]
    ,sha.[Payment Terms Code] AS 'Terms' 
    ,sla.[Product Group Code] AS 'Family'
    ,sla.[Item Category Code] 
    , CASE 
    WHEN sla.[Item Category Code]='ARMAMENT' THEN 'ARMAMENT'
    ELSE 'TAGUA'
     END AS 'Brand'
     FROM 
    [ZenUS].[dbo].[Zen Distributor Group LLC$Sales Line Archive] AS sla 

    JOIN 
    [ZenUS].[dbo].[Zen Distributor Group LLC$Sales Header Archive] AS sha
    ON
    sha.[No_]=sla.[Document No_]
    AND
    sla.[Version No_]=sha.[Version No_]

    AND
    sha.[Sell-to Customer No_]=sla.[Sell-to Customer No_]


    JOIN
    [ZenUS].[dbo].[Zen Distributor Group LLC$Item] AS i
    ON
      sla.[No_]=i.[No_] /* Obtener precio de Lista en el detalle */

     WHERE 
    sha.[Order Date] BETWEEN  CAST( CAST( @finicio AS DATE ) AS DATETIME ) AND CAST( CAST( @ffin AS DATE ) AS DATETIME )

     AND 
    sla.[Document Type]='1' /* Solo Sales Orders */


    martes, 2 de mayo de 2017 14:22
  • {...} En la base de datos el campo [Order Date] que es el que utilizo para los filtros tiene este formato: aaaa-mm-dd hh:mi:ss.mmm

    Si la columna [Order Date] es de tipo datetime entonces la forma como se almacena el valor en la base de datos es independiente a algún formato en especial, el formato que tú ves es sólo para la representación del valor, de hecho el mismo valor podría ser representado bajo otro formato según el idioma configurado.

    Dicho lo anterior, debes escribir literales de fecha bajo un formato estándar, por ejemplo YYYYMMDD (ISO 8601), por ejemplo:

    SET @finicio = '20170301';
    SET @ffin = '20170331';
    
    SELECT ...
    FROM...
    WHERE sha.[Order Date] BETWEEN @finicio AND DATEADD(DAY, 1, @ffin)
    --El rango de búsqueda afectará las filas entre: 01/03/2017 00:00:00 y 02/03/2017 00:00:00


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    martes, 2 de mayo de 2017 14:37
  • [...] En la base de datos el campo [Order Date] que es el que utilizo para los filtros tiene este formato :aaaa-mm-dd hh:mi:ss.mmm

    [...]

     WHERE 
    sha.[Order Date] BETWEEN  CAST( CAST( @finicio AS DATE ) AS DATETIME ) AND CAST( CAST( @ffin AS DATE ) AS DATETIME )

    Si es cierto que el campo [Order Date] tiene el formato que indicas, entonces ese WHERE fallará muchísimo. Me explico:

    Los campos de tipo Date o DateTime NO TIENEN FORMATO. Se guardan en binario, y el formato lo aplica el programa cliente que recibe del servidor ese dato binario y lo presenta en pantalla. En el momento de presentarlo en pantalla, es el cliente el que lo formatea como considere oportuno. El formato no queda salvado en la tabla. En consecuencia, si tu campo TIENE formato, quiere decir que no es ni date ni datetime, sino que está salvado como varchar o nvarchar.

    Cuando en el Where pones la condición de que el VARCHAR se encuentre BETWEEN dos datetimes, el servidor aplica una conversión del tipo menos prioritario al más prioritario. Esto resulta en una conversión implícita de un tipo a otro, usando el formato predeterminado que tenga el servidor en ese momento (que entre otras cosas puede depender del idioma), y en consecuencia la comparación puede arrojar cualquier resultado imprevisto debido a la discrepancia de formatos.

    Por lo tanto, es importante que averigües y distingas cuál es de verdad el tipo de dato que hay en el servidor, y que distingas los formatos almacenados en el servidor de los formatos que "ves" en el servidor a causa de su aplicación por la herramienta cliente. Dejar que se produzcan conversiones implícitas de datetime a varchar siempre causa numerosos problemas.

    martes, 2 de mayo de 2017 15:49
  • Gracias Willams por tu ayuda, también acabo de probar estos formatos : AAAA/MM/DD y AAAMMDD. Ejemplo : '2017/03/01'    '20170301', los resultados son lo mismo. Hay diferencias y es por el detalle incompleto. 

    Esto le ha ocurrido a alguien alguna ves?

    martes, 2 de mayo de 2017 18:25
  • Gracias Willams por tu ayuda, también acabo de probar estos formatos : AAAA/MM/DD y AAAMMDD. Ejemplo : '2017/03/01'    '20170301', los resultados son lo mismo. Hay diferencias y es por el detalle incompleto. 

    Esto le ha ocurrido a alguien alguna ves?

    martes, 2 de mayo de 2017 18:27