如何解决这个逻辑?

时间:2015-06-17 03:34:25

标签: sql-server sql-server-2008

我有一个包含3个变量表的查询:@result,@ order和@stock。 逻辑是库存数量必须通过批量(此处为i set = 1)分配给基于优先级(FIFO)的所有订单。股票数量必须分配到零,而配额必须< = orderqty。问题是订单之一,其allocateqty超过orderqty(优先级= 7),而其他是正确的。

DECLARE @RESULT TABLE (priority int,partcode nvarchar(50),orderqty int, runningstock int, allocateqty int)
DECLARE @ORDER TABLE(priority int,partcode nvarchar(50),orderqty int)
DECLARE @STOCK TABLE(partcode nvarchar(50),stockqty int)


INSERT INTO @ORDER (priority,partcode,orderqty)
VALUES (1,'A',10),
(2,'A',50),
(3,'A',10),
(4,'A',40),
(5,'A',3),
(6,'A',5),
(7,'A',11),
(8,'A',10),
(9,'A',10),
(10,'A',10);


INSERT INTO @STOCK(partcode,stockqty)
VALUES('A',120)

IF (SELECT SUM(orderqty)FROM @ORDER)<(SELECT stockqty FROM @STOCK)
BEGIN
 INSERT INTO @RESULT(priority,partcode,orderqty,allocateqty)
 SELECT priority, partcode,orderqty,orderqty
 FROM @ORDER
END
ELSE
BEGIN
DECLARE @allocatedqty int = 0
DECLARE @Lotsize int=1
DECLARE @allocateqty int = @Lotsize
DECLARE @runningstock int = (SELECT stockqty FROM @stock)

WHILE @runningstock>=0
BEGIN
    DECLARE @priority int
    SELECT TOP 1 @priority = priority FROM @order ORDER BY priority ASC

    WHILE @priority <= (SELECT MAX(priority) FROM @order)
    BEGIN

        DECLARE @orderqty int
        SELECT @orderqty = orderqty - @allocatedqty FROM @order WHERE priority = @priority
         SELECT @allocateqty = CASE WHEN @runningstock > 0 AND @orderqty > 0 THEN @Lotsize ELSE 0 END

        INSERT INTO @RESULT(priority,partcode,orderqty,runningstock,allocateqty)
        SELECT @priority,
               partcode, 
               CASE WHEN @orderqty >= 0 THEN @orderqty ELSE 0 END AS orderqty,
               @runningstock,
               @allocateqty
        FROM @order 
        WHERE priority = @priority

        SET @priority += 1      
        SET @runningstock = @runningstock - @allocateqty
    END
    SET @allocatedqty += @allocateqty
    IF (@runningstock <= 0) BREAK 
 END
 END
select * from @RESULT where priority=7;

SELECT priority,
sum(allocateqty) as allocated
from @RESULT
group by priority

结果:

enter image description here

2 个答案:

答案 0 :(得分:3)

我的声誉未达到50,因此无法添加评论。

你说你的其他订单是正确的,那么优先级= 7也是正确的。你可以将优先级2和4与7进行比较。它是一样的。我认为orderqty的所有循环只达到优先级7得到11的10倍,所以它会留下1。

一切都正确或一切都错了= x

修改

嗨,我找到了答案。

更改

SET @allocatedqty += @allocateqty

SET @allocatedqty += 1

因为在使用SET @allocatedqty += @allocateqty时,最后一个订单@allocateqty0,那么它始终会@allocatedqty = 0,然后它就不会增加。

希望这对你有所帮助。

编辑基于@Jesuraja给出答案应该是:

SET @allocatedqty += @Lotsize

答案 1 :(得分:0)

由于我不太确定您尝试使用哪些记录将您的库存设置为0或更高,我可以提供此功能。但它比在循环中运行所有订单要好得多。也许你会想要替换你的循环。

DECLARE @RESULT TABLE (priority int,partcode nvarchar(50),orderqty int, runningstock int, allocateqty int)
DECLARE @ORDER TABLE(priority int,partcode nvarchar(50),orderqty int)
DECLARE @STOCK TABLE(partcode nvarchar(50),stockqty int)

INSERT INTO @ORDER (priority,partcode,orderqty)
--VALUES (1,'A',10),(2,'A',50),(3,'A',10),(4,'A',40),(5,'A',3),(6,'A',5),(7,'A',11),(8,'A',10),(9,'A',10),(10,'A',10); --your orders
VALUES (1,'A',1),(2,'A',2),(3,'A',3),(4,'A',4),(5,'A',5),(6,'A',6),(7,'A',7),(8,'A',8),(9,'A',9),(10,'A',10);

INSERT INTO @STOCK(partcode,stockqty)
--VALUES('A',50) -- your stock
VALUES('A',50)

IF (SELECT SUM(orderqty) FROM @ORDER)<(SELECT stockqty FROM @STOCK)
BEGIN
    INSERT INTO @RESULT(priority,partcode,orderqty,allocateqty)
    SELECT priority, partcode,orderqty,orderqty
    FROM @ORDER
END
ELSE
BEGIN
            ;WITH dat AS(
                SELECT s.partcode, s.stockqty, o.priority, o.orderqty, 
                    ROW_NUMBER() OVER(PARTITION BY s.partcode ORDER BY o.priority DESC) as runningOrder
                FROM @Stock as s
                INNER JOIN @ORDER as o
                        ON s.partcode = o.partcode
            )
            INSERT INTO @RESULT(priority,partcode,orderqty,runningstock,allocateqty)
                SELECT d1.priority, d1.partcode, d1.orderqty, 
                    d1.stockqty - SUM(d2.orderqty) OVER(PARTITION BY d1.runningOrder) as runningstock,
                    CASE WHEN d1.stockqty - SUM(d2.orderqty) OVER(PARTITION BY d1.runningOrder) > 0 AND d1.orderqty > 0 THEN 1 ELSE 0 END 
                FROM dat as d1
                INNER JOIN dat as d2
                        ON d1.partcode = d2.partcode
                        AND d1.runningOrder >= d2.runningOrder

END
select * from @RESULT where priority=7;

SELECT priority,
sum(allocateqty) as allocated
from @RESULT
group by priority