循环依赖地狱。使用当前行中前一行的值

问题描述 投票:1回答:1

我想计算物料清单并陷入某些属性计算中。

This is link to Google sheets with all the data and needed formulas

我有现有数量(@QOH)-95安全库存(@SS)-58

DECLARE @qoh INT = 95
      , @ss  INT = 58
      , @eoq INT = 96;

CREATE TABLE #data
(
     PartId INT
  ,  SalesOrderQty INT
  , SalesDate     DATE
);

INSERT INTO #data (PartId
                 , SalesOrderQty
                 , SalesDate)
VALUES (1, 75, '20190101')
     , (1, 100, '20190201')
     , (1, 115, '20190301')
     , (1, 95, '20190401')
     , (1, 132, '20190501');

我需要计算3个实体:

  • @Supply-如果是第一条记录(20190101),然后是@QOH-@SS-#data.SalesOrderQty,否则(Previous month)@RecommendedQty - #data.SalesOrderQty

  • @EOQMultiplier-CEILING(ABS(@Supply/@eoq))

  • @RecommendedQty-如果@Supply <= 0@EOQMultiplier * @eoq ELSE @Supply

预期数据

|--------|----------|-------|---------------|-----------------|
| PartId | Date     |Supply | EOQMultiplier | RecommendedQty  |
|--------|----------|-------|---------------|-----------------|
| 1      | 20190101 | -38   | 1             | 96              |
| 1      | 20190201 | -4    | 1             | 96              |
| 1      | 20190301 | -19   | 1             | 96              |
| 1      | 20190401 | 1     | 1             | 1               |
| 1      | 20190501 | -131  | 2             | 192             |
|--------|----------|-------|---------------|-----------------|

我面临的问题是@Supply@RecommendedQty相互引用,并且由于SQL Server 2008 R2不支持某些有用的WINDOW函数,我的解决方案已经变得过于复杂和棘手]

我想计算物料清单并陷入某些属性计算中。这是所有数据和所需公式的Google表格的链接,我手头有数量(@QOH)-95安全...

sql-server sql-server-2008 sql-server-2008-r2
1个回答
0
投票

这是我推荐基于游标的解决方案的少数情况之一。它不能很好地扩展,因此如果您的数据很大,那是一个糟糕的选择,但是至少它将以一种相当容易理解的方式满足您的需求]

DECLARE @qoh INT = 95
      , @ss  INT = 58
      , @eoq INT = 96;

CREATE TABLE #data
(
     PartId INT
  ,  SalesOrderQty INT
  , SalesDate     DATE
);

INSERT INTO #data (PartId
                 , SalesOrderQty
                 , SalesDate)
VALUES (1, 75, '20190101')
     , (1, 100, '20190201')
     , (1, 115, '20190301')
     , (1, 95, '20190401')
     , (1, 132, '20190501');

;with cteOrdered as (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY PartID ORDER BY  SalesDate) as RowNum 
    FROM #data 
)
SELECT *, @QOH-@SS-SalesOrderQty as Supply, 1 as EOQMultiplier, @QOH as RecommendedQty
INTO #DataTemp 
FROM cteOrdered

DECLARE @PartId INT
DECLARE  @SalesOrderQty int
DECLARE  @SalesDate DATE 
DECLARE  @RowNum int
DECLARE  @Supply int
DECLARE  @EOQMultiplier int
DECLARE  @RecommendedQty int
DECLARE  @PrevRecQty int

DECLARE curMonth CURSOR FOR   
SELECT PartId , SalesOrderQty , SalesDate , RowNum , Supply , EOQMultiplier, RecommendedQty 
FROM #DataTemp
ORDER BY PartID, RowNum;

OPEN curMonth  

FETCH NEXT FROM curMonth   
INTO @PartId , @SalesOrderQty , @SalesDate , @RowNum , @Supply , @EOQMultiplier, @RecommendedQty

WHILE @@FETCH_STATUS = 0  
BEGIN  
    IF (@RowNum = 1) BEGIN --No prior month
        SET @Supply = @QOH - @SS - @SalesOrderQty
    END ELSE BEGIN
        SET @Supply = @PrevRecQty - @SalesOrderQty 
    END
    SET @EOQMultiplier = CEILING(ABS(@Supply*1.0/@eoq))
    if (@Supply <= 0) BEGIN
        SET @RecommendedQty = @EOQMultiplier * @eoq 
    END ELSE BEGIN 
        SET @RecommendedQty = @Supply
    END

    SET @PrevRecQty = @RecommendedQty

    UPDATE #DataTemp 
    SET Supply = @Supply, EOQMultiplier = @EOQMultiplier, RecommendedQty= @RecommendedQty
    WHERE PartId = @PartId AND RowNum = @RowNum

    FETCH NEXT FROM curMonth   
    INTO @PartId , @SalesOrderQty , @SalesDate , @RowNum , @Supply , @EOQMultiplier, @RecommendedQty
END   
CLOSE curMonth;  
DEALLOCATE curMonth; 

SELECT * FROM #DataTemp 

DROP TABLE #data 
DROP TABLE #DataTemp 
© www.soinside.com 2019 - 2024. All rights reserved.