Published on

November 25, 2011

Manejo de Resta en Ejecución en SQL Server

En esta publicación del blog, discutiremos una consulta SQL que maneja una resta en ejecución para calcular las cantidades recibidas frente a las cantidades esperadas. Esta consulta fue inspirada por una publicación en un foro en el sitio web SQLTeam.

La pregunta original se trataba de mostrar las cantidades recibidas frente a las cantidades esperadas, y si había alguna escasez, debería mostrarse en la última línea. El primer conjunto de resultados proporcionado en la pregunta se veía así:

ArtículoCantidad EsperadaCantidad RecibidaEscasez
Artículo0130455
Artículo0120455
Artículo0240382
Artículo03509010
Artículo03309010
Artículo03209010

El objetivo era transformar este conjunto de resultados en un segundo conjunto de resultados, donde las cantidades recibidas se ajustan en función de las cantidades esperadas. El segundo conjunto de resultados debería verse así:

ArtículoCantidad EsperadaCantidad RecibidaEscasez
Artículo0130300
Artículo0120155
Artículo0240382
Artículo0350500
Artículo0330300
Artículo03201010

La consulta proporcionada en la publicación del foro tenía algunas limitaciones en términos de escalabilidad, pero funcionaba bien para conjuntos de datos más pequeños. Aquí hay un ejemplo de la consulta:

SELECT ex.articulo,
       ex.CantidadEsperada,
       ex.CantidadEsperada - CASE
                          WHEN Escasez > umbralParaEscasez AND Escasez - umbralParaEscasez <= CantidadEsperada THEN Escasez - umbralParaEscasez
                          WHEN Escasez > umbralParaEscasez AND Escasez - umbralParaEscasez > CantidadEsperada THEN CantidadEsperada
                          ELSE 0
                      END AS 'CantidadRecibida',
       CASE
           WHEN Escasez > umbralParaEscasez AND Escasez - umbralParaEscasez <= CantidadEsperada THEN Escasez - umbralParaEscasez
           WHEN Escasez > umbralParaEscasez AND Escasez - umbralParaEscasez > CantidadEsperada THEN CantidadEsperada
           ELSE 0
       END AS 'EscasezTotal'
FROM (
    SELECT e1.dt,
           e1.articulo,
           ISNULL(SUM(e2.CantidadEsperada), 0) AS 'umbralParaEscasez'
    FROM Esperado e1
    LEFT JOIN Esperado e2 ON e1.articulo = e2.articulo AND e1.dt < e2.dt
    GROUP BY e1.dt, e1.articulo
) minValEscasez
INNER JOIN Esperado ex ON ex.articulo = minValEscasez.articulo AND ex.dt = minValEscasez.dt
INNER JOIN Recibido rec ON minValEscasez.articulo = rec.articulo

La consulta utiliza una tabla derivada para calcular el umbral para el valor de “Escasez”. Luego une esta tabla derivada con las tablas “Esperado” y “Recibido” para calcular las cantidades recibidas ajustadas.

El autor de la consulta explicó su proceso de pensamiento al llegar a la solución. Primero analizó los requisitos y los datos proporcionados. Luego creó las tablas necesarias y datos ficticios para probar su consulta. Después de varias iteraciones, logró obtener el resultado deseado y publicó su solución.

Es importante tener en cuenta que si bien esta consulta funciona bien para conjuntos de datos más pequeños, es posible que no sea escalable para conjuntos de datos más grandes. El autor mencionó que comienza a volverse lento cuando hay más de 500,000 a 600,000 registros en la tabla “Esperado”. Por lo tanto, es importante considerar el tamaño de los datos al utilizar este enfoque.

En conclusión, la consulta discutida en esta publicación del blog proporciona una solución para manejar una resta en ejecución en SQL Server. Permite el cálculo de las cantidades recibidas frente a las cantidades esperadas, teniendo en cuenta cualquier escasez. Si bien puede no ser adecuada para conjuntos de datos grandes, puede ser un enfoque útil para problemas más pequeños con estructuras similares.

Click to rate this post!
[Total: 0 Average: 0]

Let's work together

Send us a message or book free introductory meeting with us using button below.