我的SQL查询似乎处于循环中

时间:2014-03-07 03:56:35

标签: sql sql-server

我有一个表格,列出了我的广告资源中的项目,total quantity on handordered qtyship date


    +-------+-----------+------------+----------+
    | Item  | QtyOnHand | QtyOrdered | ShipDate |
    +-------+-----------+------------+----------+
    | Itema | 100       | 80         | 3/4/14   |
    | Itemb | 80        | 220        | 3/8/14   |
    | Itema | 100       | 80         | 3/10/14  |
    | Itemb | 80        | 100        | 3/12/14  |
    +-------+-----------+------------+----------+

我正在尝试创建一个查询,该查询将按日期(PromiseDate)顺序按项目滚动销售订单。使用已知库存量(QtyOnHand)减去每个订单的QtyOrdered量,并在减去QtyOrdered后保持QtyOnHand的运行总和,并且当QtyOnHand为<时,仅写入我的表。 1这样我知道特定项目的日期将不在库存中。

处理完后续数据后,我的新表应该包含两个记录,每个记录代表一个项目用完库存的日期。

请帮助。 谢谢

CREATE TABLE #OverInv (Item VARCHAR(15), PromiseDate DATETIME, QtyOnHand INT, QtyOrdered INT, TotalOver INT) 
DECLARE @Item VARCHAR(15),
 @PromiseDate DATETIME,
 @QtyOrdered INT,
 @QtyOnHand INT,
 @CurrentItem VARCHAR(15),
 @TotalOver INT 

 SET @TotalOver = 0
 SET @CurrentItem = 0

 DECLARE rt_cursor CURSOR 
 FOR 
 SELECT Item, PromiseDate, QtyOrdered, QtyOnHand 
 FROM Inventory 

 OPEN rt_cursor 

 FETCH NEXT FROM rt_cursor INTO @Item,@PromiseDate,@QtyOrdered,@QtyOnHand 
 WHILE @@FETCH_STATUS = 0

IF @CurrentItem = 0
  BEGIN 
    SET @CurrentItem = @Item
    SET @TotalOver = (@QtyOnHand - @QtyOrdered)

    IF @TotalOver < 1 
       BEGIN
          INSERT #OverInv VALUES (@Item,@PromiseDate,@QtyOnHand,@QtyOrdered,@TotalOver) 
          FETCH NEXT FROM rt_cursor INTO @Item,@PromiseDate,@QtyOrdered,@QtyOnHand 
          SET @TotalOver = 0
       END
    ELSE
       BEGIN
          FETCH NEXT FROM rt_cursor INTO @Item,@PromiseDate,@QtyOrdered,@QtyOnHand
       END
  END

IF @CurrentItem = @Item
  SET @TotalOver = (@TotalOver - @QtyOrdered)
  BEGIN
    IF @TotalOver < 1
       BEGIN
         INSERT #OverInv VALUES (@Item,@PromiseDate,@QtyOnHand,@QtyOrdered,@TotalOver) 
         FETCH NEXT FROM rt_cursor INTO @Item,@PromiseDate,@QtyOrdered,@QtyOnHand 
         SET @TotalOver = 0
       END
    ELSE
       BEGIN
         FETCH NEXT FROM rt_cursor INTO @Item,@PromiseDate,@QtyOrdered,@QtyOnHand
       END
  END

IF @CurrentItem <> @Item
   SET @CurrentItem = @Item
   SET @TotalOver = (@QtyOnHand - @QtyOrdered)
   BEGIN  
     IF @TotalOver < 1 
        BEGIN
          INSERT #OverInv VALUES (@Item,@PromiseDate,@QtyOnHand,@QtyOrdered,@TotalOver) 
          FETCH NEXT FROM rt_cursor INTO @Item,@PromiseDate,@QtyOrdered,@QtyOnHand 
          SET @TotalOver = 0
        END
     ELSE
       BEGIN
         FETCH NEXT FROM rt_cursor INTO @Item,@PromiseDate,@QtyOrdered,@QtyOnHand
       END
   END


CLOSE rt_cursor 
DEALLOCATE rt_cursor 

SELECT * FROM #OverInv ORDER BY Item 

DROP TABLE #OverInv

1 个答案:

答案 0 :(得分:0)

你可以在没有游标的情况下做到这一点。首先,您需要以下列格式输入数据:

Item |  QtyOnHand  | Initial date
Item | -QtyOrdered | ShipDate 

然后你需要按项目和日期加总。接下来,您计算数量的运行总和。最后选择数量为负的最小日期。这是完整的查询:

with cte1 as
(
  -- assuming QtyOnHand is the same in all Inventory rows
  select Item, min(QtyOnHand) as QtyOnHand, min(ShipDate) as ShipDate 
  from Inventory
  group by Item

  union all

  select Item, -QtyOrdered as QtyOnHand, ShipDate 
  from Inventory
)
, cte2 as
(
  -- only one row per item and date
  select Item, SUM(QtyOnHand) as QtyOnHand, ShipDate
  from cte1
  group by Item, ShipDate
)
, cte3 as
(
  select 
    Item,
    SUM(QtyOnHand) OVER(partition by item order by ShipDate) as QtyOnHand,
    ShipDate
  from
    cte2
)
select Item, min(ShipDate) as ShipDate
from cte3
where QtyOnHand < 0
group by Item

SUM()OVER()需要SQL Server 2012,但还有其他方法可以计算运行总和。查看fiddle