Перерасчет запасов с учетом окончательного значения - PullRequest
0 голосов
/ 22 мая 2018

Я кодирую сценарий SQL Server, чтобы сделать перерасчет инвентарного количества конкретного SKU с сегодняшнего дня за последние 365 дней, учитывая фактический запас.В скрипте я делаю много манипуляций с очисткой данных.В конце вывод выводится из временной таблицы, как представлено:

SELECT
    DATE,
    SUM(CASE WHEN MOV='IN' THEN 1 ELSE 0 END) AS TRANSACTION_IN, --COUNT TRANSACTIONS IN
    SUM(CASE WHEN MOV='OUT' THEN 1 ELSE 0 END) AS TRANSACTION_OUT, --COUNT TRANSACTIONS OUT
    SUM(CASE WHEN MOV ='IN' THEN QTD ELSE 0 END) AS SUM_IN, --SUM QUANTITY IN
    SUM(CASE WHEN MOV ='OUT' THEN QTD ELSE 0 END) AS SUM_OUT --SUM QUANTITY IN
FROM #MOVIMENTS
GROUP BY DT
ORDER BY DT

Ниже можно увидеть пример вывода SQL, показанного:

Пример таблицы

В таблице представлена ​​сумма транзакций, а также количество входов и выходов склада, сгруппированных по дате.Мое намерение состоит в том, чтобы добавить столбец с именем «STOCK», который представляет уровень запаса SKU на текущий день.Для этого у меня есть фактический уровень запасов.Так что мне нужно пересчитать все уровни запасов изо дня в день по всем рядам дат.

В Excel это просто.Я могу поместить фактический уровень в последнюю строку (например, 10) и просто расширить расчет (формула, представленная на рисунке), пока не достигну вершины.В представленном виде (столбец E - это формула, столбец G - это выходные данные):

Перерасчет запасов в Excel

Может ли кто-нибудь помочь мне достичь этого результата в SQL Server?

В Python я нашел решение , использующее Pandas, но я бы предпочел реализовать это вычисление внутри скрипта SQL.

Ответы [ 3 ]

0 голосов
/ 22 мая 2018

Вам нужна текущая (или оконная) сумма.

;WITH PartialResults AS
(
    SELECT
        DATE,
        SUM(CASE WHEN MOV='IN' THEN 1 ELSE 0 END) AS TRANSACTION_IN, --COUNT TRANSACTIONS IN
        SUM(CASE WHEN MOV='OUT' THEN 1 ELSE 0 END) AS TRANSACTION_OUT, --COUNT TRANSACTIONS OUT
        SUM(CASE WHEN MOV ='IN' THEN QTD ELSE 0 END) AS SUM_IN, --SUM QUANTITY IN
        SUM(CASE WHEN MOV ='OUT' THEN QTD ELSE 0 END) AS SUM_OUT --SUM QUANTITY IN
    FROM #MOVIMENTS
    GROUP BY DT
)
SELECT
    P.*,
    RunningSum = SUM(P.SUM_IN + P.SUM_OUT) OVER (ORDER BY P.Date ASC)
FROM
    PartialResults AS P
0 голосов
/ 22 мая 2018

Пример SQL Fiddle

Основываясь на идее @EzLo, я выясняю решение этой проблемы.

DECLARE @cum_sum float -- scalar cumulated sum
DECLARE @last_stock float = 10 -- current stock level

-- get the last value of the cumulated sum 
SELECT TOP 1 @cum_sum = SUM(SUM_IN + SUM_OUT) OVER (ORDER BY Date ASC) FROM t ORDER BY DATE DESC

-- final select
SELECT 
  *,
  RunningSum = SUM(SUM_IN + SUM_OUT) OVER (ORDER BY Date ASC) - (@cum_sum - @last_stock)
FROM t

Есть ли более простой способ сделатьэто?

0 голосов
/ 22 мая 2018

Пример SQL FIDDLE

SELECT
    DATE,
    SUM(CASE WHEN MOV='IN' THEN 1 ELSE 0 END) AS TRANSACTION_IN, --COUNT TRANSACTIONS IN
    SUM(CASE WHEN MOV='OUT' THEN 1 ELSE 0 END) AS TRANSACTION_OUT, --COUNT TRANSACTIONS OUT
    SUM(CASE WHEN MOV ='IN' THEN QTD ELSE 0 END) AS SUM_IN, --SUM QUANTITY IN
    SUM(CASE WHEN MOV ='OUT' THEN QTD ELSE 0 END) AS SUM_OUT --SUM QUANTITY IN
INTO #newtable
FROM #MOVIMENTS t1
GROUP BY DT
ORDER BY DT

select t1.DATE, t1.TRANSACTION_IN, t1.TRANSACTION_OUT, t1.SUM_IN, t1.SUM_OUT, SUM(t2.SUM_IN + t2.SUM_OUT) as STOCK
from #newtable t1
inner join #newtable t2 on t1.DATE >= t2.DATE
group by t1.DATE, t1.TRANSACTION_IN, t1.TRANSACTION_OUT, t1.SUM_IN, t1.SUM_OUT
order by t1.DATE
...