Я почти уверен, что ответ - это некий вариант запроса SUM OVER.
Вы правы. Вы можете поиграть с Rows-Range thing
, чтобы попасть туда.
Попробуйте этот сценарий,
CREATE TABLE #Order(OrderId int,OrderDetailId int, ItemId int, QtyOrdered int, DateNeeded date)
insert into #Order values
(16669 , 36915, 139, 10 ,'2019-10-21'),(16669 , 36916, 139, 15 ,'2019-11-21')
,(16670 , 36917, 11 , 1 ,'2019-10-21'),(16673 , 36922, 250, 5 ,'2019-10-11')
,(16673 , 36923, 139, 10 ,'2019-10-11')
CREATE TABLE #OrderAllocation (OrderId int, ItemId int, ItemLot bigint, QtyAllocated int)
insert into #OrderAllocation values
(16669,139,2345678, 2 ),(16669, 139,2256245,3)
,(16669,139,2356245, 10),(16673, 139,2356245,8)
,(16673,139,2245689, 2),(16673, 250,2019001,5);
WITH CTE
AS (SELECT OrderId,
ItemId,
SUM(QtyAllocated) TotalAlloc
FROM #OrderAllocation
GROUP BY OrderId,
ItemId),
CTE1
AS (SELECT o.OrderId,
o.OrderDetailId AS DetailId,
o.ItemId,
o.QtyOrdered AS OrderQty,
ISNULL(TotalAlloc, 0) TotalAlloc,
SUM(QtyOrdered) OVER(PARTITION BY o.OrderId,
o.ItemId
ORDER BY o.dateneeded ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) RunningAllocQty,
DateNeeded
FROM #Order O
LEFT JOIN CTE C ON o.OrderId = c.orderid
AND o.ItemId = c.ItemId)
SELECT OrderId,
DetailId,
ItemId,
OrderQty,
TotalAlloc,
CASE
WHEN TotalAlloc > 0
THEN OrderQty - ISNULL(RunningAllocQty, 0)
ELSE 0
END AllocQty,
CASE
WHEN TotalAlloc > 0
THEN OrderQty - (OrderQty - ISNULL(RunningAllocQty, 0))
ELSE OrderQty
END BackOrderQty
FROM CTE1;
drop table #Order,#OrderAllocation
В этом сценарии вы можете исправить join condition
, если он неверен.
Запрос может быть оптимизирован после ознакомления с данными. В этих небольших выборочных данных так много сомнений.