Обновить столбец SQL на основе остатка, перенесенного из предыдущих строк

У меня есть таблица, которая выглядит так:

Номер документа Источник Лок Бин Элемент Требуется_SOH Доступно_SOH 3 А ЗА 3 АВС 17560 25000 5 А ЗА 3 АВС 5810 НУЛЕВОЙ 6 А ЗА 3 АВС 3249 НУЛЕВОЙ 2 Б ГБ 5 ГЭФ 5000 2000 г. 7 Б ГБ 5 ГЭФ 200 НУЛЕВОЙ 8 Б ГБ 5 ГЭФ 300 НУЛЕВОЙ

Мне нужно взять Available_SOH из самого раннего DocNum и вычесть его из Required_SOH, а затем обновить Available_SOH, указав остаток в следующем DocNum. Это будет справедливо для каждой комбинации источника, местоположения, ячейки и позиции.

Таким образом, используя приведенный выше пример данных для комбинации Source, Loc, Bin, Item (A, ZA, 3, ABC), самый ранний DocNum равен 3 и, следовательно, ему присвоено значение Available_SOH. Обратите внимание, что всем самым ранним номерам документов в таблице для соответствующей комбинации присвоено значение SOH, которое в данном случае указывает на доступный запас для этого конкретного товара (ABC).
Мне нужно взять баланс 7440 (Avail_SOH 25000 - Req_SOH 17560) и назначить его Availabe_SOH для DocNum 5, потому что это следующий DocNum для этой комбинации. Затем следуйте той же логике, что и Avail_SOH 7440 — Req_SOH 5810 = 1630, которая перейдет в Available_SOH для DocNum 6.

Поэтому результат будет выглядеть так:

Номер документа Источник Лок Бин Элемент Требуется_SOH Доступно_SOH 3 А ЗА 3 АВС 17560 25000 5 А ЗА 3 АВС 5810 7440 6 А ЗА 3 АВС 3249 1630 г. 2 Б ГБ 5 ГЭФ 5000 2000 г. 7 Б ГБ 5 ГЭФ 200 -3000 8 Б ГБ 5 ГЭФ 300 -3200

Короче говоря, мне нужно перенести остаток запаса на следующий DocNum для комбинации Source, Loc, Bin, Item. По сути, номера DocNums, которые были созданы первыми, получают выполнение запасов.

Мне очень сложно сформулировать, что мне нужно, но я надеюсь, что это имеет смысл.

Это то, что я пробовал, но это не дает желаемого результата

WITH OrderedData AS (
    SELECT
        DocNum,
        Source,
        Loc,
        Bin,
        Item,
        Required_SOH,
        COALESCE(Available_SOH, 0) AS SOH,
        ROW_NUMBER() OVER (PARTITION BY Source, Loc, Bin, Item ORDER BY DocNum) AS RowNum
    FROM #TempSOH
),
CalculatedSOH AS (
    SELECT
        DocNum,
        Source,
        Loc,
        Bin,
        Item,
        Required_SOH,
        Available_SOH,
        SUM(Available_SOH) OVER (PARTITION BY Source, Loc, Bin, Item ORDER BY RowNum ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - Required_SOH AS SOH_Calculated
    FROM OrderedData
)
SELECT
    DocNum,
    Source,
    Loc,
    Bin,
    Item,
    Required_SOH,
    CASE
        WHEN ROW_NUMBER() OVER (PARTITION BY Source, Loc, Bin, Item ORDER BY DocNum) = 1 THEN SOH_Calculated
        ELSE LAG(SOH_Calculated, 1, 0) OVER (PARTITION BY Source, Loc, Bin, Item ORDER BY DocNum)
    END AS SOH
FROM CalculatedSOH
ORDER BY DocNum;
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
0
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я не проверял это, но думаю, что это сделает то, что вы просите.

Я думаю, что вместо использования оконных функций лучший способ получить промежуточную сумму — это соединить таблицу с самой собой, используя >= в DocNum, который объединит предыдущие значения, которые затем можно суммировать, чтобы вычесть из текущего значения.

Я вижу здесь недостаток, если значение Available_SOH когда-либо будет изменено так, чтобы оно было ниже, чем первый документ минус объединенный предыдущий Required_SOH, так ли это когда-либо?

select 
     current.DocNum
    ,current.Source
    ,current.Loc
    ,current.Bin
    ,current.Item
    ,current.Required_SOH
    ,max(history.Available_SOH) - sum(history.Required_SOH) as Available_SOH

from #TempSOH as current
inner join #TempSOH as history on current.Source = history.Source
                        and current.Loc = history.Loc
                        and current.Bin = history.Bin
                        and current.Item = history.Item
                        and current.DocNum >= history.DocNum

group by 
     current.DocNum
    ,current.Source
    ,current.Loc
    ,current.Bin
    ,current.Item
    ,current.Required_SOH
    ,current.Available_SOH
Ответ принят как подходящий

Доступная стоимость рассчитывается как разница между
текущий итог для Availible_SOH
и
текущий итог для Ruquired_SOH без текущей строки — поскольку «доступен» для текущей строки.

См. пример

select *
  ,sum(Available_SOH)over(partition by Source, Loc, Bin, Item ORDER BY DocNum) 
   -sum(Required_SOH)over(partition by Source, Loc, Bin, Item ORDER BY DocNum)
   +Required_SOH newAvailable_SOH
from #TempSOH
Номер документа Источник Лок Бин Элемент Требуется_SOH Доступно_SOH newAvailable_SOH 3 А ЗА 3 АВС 17560 25000 25000 5 А ЗА 3 АВС 5810 нулевой 7440 6 А ЗА 3 АВС 3249 нулевой 1630 г. 2 Б ГБ 5 ГЭФ 5000 2000 г. 2000 г. 7 Б ГБ 5 ГЭФ 200 нулевой -3000 8 Б ГБ 5 ГЭФ 300 нулевой -3200

Там выражение

  ,sum(Available_SOH)over(partition by Source, Loc, Bin, Item ORDER BY DocNum) 
   -sum(Required_SOH)over(partition by Source, Loc, Bin, Item ORDER BY DocNum)
   +Required_SOH newAvailable_SOH

равен

  ,sum(Available_SOH)over(partition by Source, Loc, Bin, Item ORDER BY DocNum) 
   -coalesce(sum(Required_SOH)over(partition by Source, Loc, Bin, Item ORDER BY DocNum
                          rows between unbounded preceding and 1 preceding)
            ,0)

рабочий пример

Это именно то, что я искал! сработало отлично, большое спасибо!

Sauce 30.08.2024 17:20

Другие вопросы по теме