SQL Server 2008,根据订单类型和订单日期时间将库存分配到销售订单的数量

时间:2015-04-24 03:04:36

标签: sql-server

我根据下面的订单类型将FIFO分配到销售订单:

DECLARE @tblOrder TABLE
    (DealerCode NVARCHAR(50),
     PartCode NVARCHAR(50),
     OrderQty INT,
     OrderType NVARCHAR(50)
    )
INSERT  INTO @tblOrder
        ( DealerCode,
          PartCode,
          OrderQty,
          OrderType )
VALUES  ('D1','A',19,'Urgent'),
('D2','B',10,'Normal'),
('D3','C',11,'HotLine'),
('D1','D',20,'Normal'),
('D2','E',12,'Normal'),
('D2','D',40,'Normal');

DECLARE @tblStock TABLE
    (PartCode NVARCHAR(50),
     StockQty INT)
INSERT  INTO @tblStock
        ( PartCode,
          StockQty)
VALUES  ('A',20),
('B',15),
('C',9),
('D',30),
('E',0)

;WITH ordertemp AS (
select ord.dealercode, 
      ord.partcode, 
      ord.orderqty, 
      ord.ordertype,
      ROW_NUMBER() OVER (ORDER BY case ord.ordertype when 'HotLine' then 1 when 'Urgent' then 2 else 3 end, ord.partcode, ord.dealercode) 'StockPriority',
      sto.stockqty 'InitialStock'
from @tblorder ord
left outer join @tblstock sto
on ord.partcode = sto.partcode )

SELECT
    Orders.dealercode,
    Orders.partcode,
    CASE    WHEN Backlog.PriorQty > Orders.InitialStock THEN 0
            ELSE Orders.InitialStock - Backlog.PriorQty END 'Stock',
    Orders.orderqty,
    CASE    WHEN Backlog.PriorQty + Orders.OrderQty < Orders.InitialStock THEN Orders.OrderQty 
            WHEN Backlog.PriorQty > Orders.InitialStock THEN 0
            ELSE Orders.InitialStock - Backlog.PriorQty END 'Allocated',
    Orders.ordertype
FROM 
    ordertemp Orders
    INNER JOIN
    (
    SELECT A.stockpriority, A.partcode, ISNULL(SUM(B.orderqty),0) 'PriorQty'
    from ordertemp A
    LEFT OUTER JOIN ordertemp B
    on A.partcode = B.partcode
    and A.stockpriority > B.stockpriority 
    group by A.stockpriority, A.partcode ) Backlog
    ON Orders.stockpriority = Backlog.stockpriority
ORDER BY Orders.StockPriority

结果:

dealercode  partcode    Stock   orderqty    Allocated   ordertype
D3  C   9   11  9   HotLine
D1  A   20  19  19  Urgent
D2  B   15  10  10  Normal
D1  D   30  20  20  Normal
D2  D   10  40  10  Normal
D2  E   0   12  0   Normal

我更愿意平等分配。恩。 partcode D(Stock = 30,orderqty 20&amp; 40 =&gt; Allocated(15,15)。请帮助我。

更新 更新的逻辑按qty = 1分配给每个部分一次,并循环所有部分直到stock = 0

DECLARE @tblOrder TABLE
    (DealerCode NVARCHAR(50),
     PartCode NVARCHAR(50),
     OrderQty INT,
     OrderType NVARCHAR(50)
    )
INSERT  INTO @tblOrder
        ( DealerCode,
          PartCode,
          OrderQty,
          OrderType )
VALUES  ('D1','A',19,'Urgent'),
('D2','A',10,'Normal'),
('D3','A',11,'HotLine'),
('D1','A',20,'Normal'),
('D2','A',12,'Normal'),
('D1','A',40,'Normal');

DECLARE @tblStock TABLE
    (PartCode NVARCHAR(50),
     StockQty INT)
INSERT  INTO @tblStock
        ( PartCode,
          StockQty)
VALUES  ('A',100);

;WITH ordertemp AS (
select ord.dealercode, 
      ord.partcode, 
      ord.orderqty, 
      ord.ordertype,
      ROW_NUMBER() OVER (ORDER BY case ord.ordertype when 'HotLine' then 1 when 'Urgent' then 2 else 3 end, ord.partcode, ord.dealercode) 'StockPriority',
      sto.stockqty 'InitialStock'
from @tblorder ord
left outer join @tblstock sto
on ord.partcode = sto.partcode )

SELECT
    Orders.dealercode,
    Orders.partcode,
    CASE    WHEN Backlog.PriorQty > Orders.InitialStock THEN 0
            ELSE Orders.InitialStock - Backlog.PriorQty END 'Stock',
    Orders.orderqty,
    CASE    WHEN Backlog.PriorQty + Orders.OrderQty < Orders.InitialStock THEN Orders.OrderQty 
            WHEN Backlog.PriorQty > Orders.InitialStock THEN 0
            ELSE Orders.InitialStock - Backlog.PriorQty END 'Allocated',
    Orders.ordertype
FROM 
    ordertemp Orders
    INNER JOIN
    (
    SELECT A.stockpriority, A.partcode, ISNULL(SUM(B.orderqty),0) 'PriorQty'
    from ordertemp A
    LEFT OUTER JOIN ordertemp B
    on A.partcode = B.partcode
    and A.stockpriority > B.stockpriority 
    group by A.stockpriority, A.partcode ) Backlog
    ON Orders.stockpriority = Backlog.stockpriority
ORDER BY Orders.StockPriority

按顺序分配的FIFO结果:

dealercode  partcode    Stock   orderqty    Allocated   ordertype
D3  A   100 11  11  HotLine
D1  A   89  19  19  Urgent
D1  A   70  20  20  Normal
D1  A   50  40  40  Normal
D2  A   10  12  10  Normal
D2  A   0   10  0   Normal

我更喜欢按orderty = 1分配的FIFO,因此结果更准确:

dealercode  partcode    Stock   orderqty    Allocated   ordertype
D3  A   100 11  11  HotLine
D1  A   89  19  19  Urgent
D1  A   70  20  20  Normal
D1  A   50  40  28  Normal
D2  A   22  12  12  Normal
D2  A   10  10  10  Normal
在由qty = 1分配给所有订单的Excel中的

enter image description here

2 个答案:

答案 0 :(得分:0)

您应首先获得优先级部件的总订单数和总订单数量。基于此,您可以计算延期交货的剩余库存是否足以满足此优先级的总订单,或者是否需要平均分配。 这样的事情。

数据

DECLARE @tblOrder TABLE
    (DealerCode NVARCHAR(50),
     PartCode NVARCHAR(50),
     OrderQty INT,
     OrderType NVARCHAR(50)
    )
INSERT  INTO @tblOrder
        ( DealerCode,
          PartCode,
          OrderQty,
          OrderType )
VALUES  ('D1','A',19,'Urgent'),
('D2','B',10,'Normal'),
('D3','C',11,'HotLine'),
('D1','D',20,'Normal'),
('D2','E',12,'Normal'),
('D2','D',40,'Normal');

DECLARE @tblStock TABLE
    (PartCode NVARCHAR(50),
     StockQty INT)
INSERT  INTO @tblStock
        ( PartCode,
          StockQty)
VALUES  ('A',20),
('B',15),
('C',9),
('D',30),
('E',0)

<强>查询

;WITH ordertemp AS 
(
select ord.dealercode, 
      ord.partcode, 
      ord.orderqty, 
      ord.ordertype,
      RANK() OVER (ORDER BY case ord.ordertype when 'HotLine' then 1 when 'Urgent' then 2 else 3 end, ord.partcode) 'StockPriority',
      ROW_NUMBER()OVER(PARTITION BY case ord.ordertype when 'HotLine' then 1 when 'Urgent' then 2 else 3 end, ord.partcode ORDER BY dealercode) rownum,
      sto.stockqty 'InitialStock'
from @tblorder ord
left outer join @tblstock sto
on ord.partcode = sto.partcode 
), ordercounttemp AS
(
    SELECT StockPriority,partcode,COUNT(*) totalorders, SUM(orderqty) totalorderqty 
    FROM ordertemp
    GROUP BY StockPriority,partcode
)
SELECT ot.DealerCode,ot.PartCode,
CASE WHEN backorder.totalorderqty > InitialStock THEN 0 ELSE ((InitialStock - backorder.totalorderqty)*(temp.totalorders - rownum + 1)/temp.totalorders)  END 'Stock',
ot.orderqty,
CASE WHEN (InitialStock - backorder.totalorderqty) > temp.totalorderqty THEN InitialStock - backorder.totalorderqty ELSE (CASE WHEN backorder.totalorderqty > InitialStock THEN 0 ELSE InitialStock - backorder.totalorderqty  END) / temp.totalorders END StockAllocated,
ot.ordertype
FROM ordertemp ot
INNER JOIN ordercounttemp temp
ON ot.PartCode = temp.PartCode
AND ot.StockPriority = temp.StockPriority
INNER JOIN 
(
SELECT A.stockpriority, A.partcode, ISNULL(SUM(B.totalorderqty),0) totalorderqty,ISNULL(SUM(B.totalorders),0) totalorders 
from ordercounttemp A
    LEFT OUTER JOIN ordercounttemp B
    on A.partcode = B.partcode
    AND A.stockpriority > B.stockpriority
GROUP BY A.stockpriority, A.partcode
)backorder
ON backorder.PartCode = temp.PartCode
AND backorder.StockPriority = temp.StockPriority
ORDER BY ot.StockPriority,ot.DealerCode

修改

如果您想根据日期/时间更改分配,请使用ORDER BY更改为ORDER BY case ord.ordertype when 'HotLine' then 1 when 'Urgent' then 2 else 3 end, ord.partcode, ord.OrderDt。查看下面的查询。

DECLARE @tblOrder TABLE
    (DealerCode NVARCHAR(50),
     PartCode NVARCHAR(50),
     OrderQty INT,
     OrderType NVARCHAR(50),
     OrderDt DATETIME
    )
INSERT  INTO @tblOrder
        ( DealerCode,
          PartCode,
          OrderQty,
          OrderType,
          OrderDt)
VALUES  ('D1','A',19,'Urgent','2015-04-15'),
('D2','A',10,'Normal','2015-04-16'),
('D3','A',11,'HotLine','2015-04-17'),
('D1','A',20,'Normal','2015-04-18'),
('D2','A',12,'Normal','2015-04-19'),
('D1','A',40,'Normal','2015-04-20');

DECLARE @tblStock TABLE
    (PartCode NVARCHAR(50),
     StockQty INT)
INSERT  INTO @tblStock
        ( PartCode,
          StockQty)
VALUES  ('A',38);

;WITH ordertemp AS (
select ord.dealercode, 
      ord.partcode, 
      ord.orderqty, 
      ord.ordertype,
      ROW_NUMBER() OVER (ORDER BY case ord.ordertype when 'HotLine' then 1 when 'Urgent' then 2 else 3 end, ord.partcode, ord.OrderDt) 'StockPriority',
      sto.stockqty 'InitialStock',ord.OrderDt
from @tblorder ord
left outer join @tblstock sto
on ord.partcode = sto.partcode )

SELECT
    Orders.dealercode,
    Orders.partcode,
    CASE    WHEN Backlog.PriorQty > Orders.InitialStock THEN 0
            ELSE Orders.InitialStock - Backlog.PriorQty END 'Stock',
    Orders.orderqty,
    CASE    WHEN Backlog.PriorQty + Orders.OrderQty < Orders.InitialStock THEN Orders.OrderQty 
            WHEN Backlog.PriorQty > Orders.InitialStock THEN 0
            ELSE Orders.InitialStock - Backlog.PriorQty END 'Allocated',
    Orders.ordertype,OrderDt
FROM 
    ordertemp Orders
    INNER JOIN
    (
    SELECT A.stockpriority, A.partcode, ISNULL(SUM(B.orderqty),0) 'PriorQty'
    from ordertemp A
    LEFT OUTER JOIN ordertemp B
    on A.partcode = B.partcode
    and A.stockpriority > B.stockpriority 
    group by A.stockpriority, A.partcode ) Backlog
    ON Orders.stockpriority = Backlog.stockpriority
ORDER BY Orders.StockPriority

答案 1 :(得分:0)

抱歉 - 忙碌的一天,不能在那一刻完成。

简短版本 - 从逻辑上讲,您的订购需要基于部分,优先级,然后订单金额递增。您需要在运行时考虑运行总计,较小的订单可能小于均布分配。这会给你留下一些奇怪的空白。

您的&#34;先前&#34;分配必须基于先前的优先级&#34;仅数量。然后,您必须对该组内的分发进行计算。

在这里举行大量的会议并等待会议 - 抱歉无法提供更多帮助。