2011-08-25 88 views
2

我希望根据最优批量(OLQ)来拆分订单以生成多个工单,这意味着工单中的数量总和不会超过OLQ 。根据条件将数据行分成多行的SQL脚本

这里是我的订单表的样本数据:

Order Item Product Qty 
OR-01 I-001 PRD-01 70 
OR-01 I-001 PRD-02 15 
OR-01 I-001 PRD-03 55 

的OLQ该订单是30,因此工单的数量的总和不应超过30但工作顺序可以有多个产品同一项目(项目是产品的父项)。
这里是我要拆分这个以OLQ的基础上创建工作单:

Order WorkOrd Seq Item Product Qty 
OR-01 WO-0001 001 I-001 PRD-01 30 
OR-01 WO-0002 001 I-001 PRD-01 30 
OR-01 WO-0003 001 I-001 PRD-01 10 
OR-01 WO-0003 002 I-001 PRD-02 15 
OR-01 WO-0003 003 I-001 PRD-03 5 
OR-01 WO-0004 001 I-001 PRD-03 30 
OR-01 WO-0005 001 I-001 PRD-03 20 

注意,WO-0003有三个产品,10,15日和5金额为30.注意,最后的工单WO-0005只有20个数量(剩余的)。

在附件中,我突出了不同颜色的工作订单以便于理解。 Order to Work Order conversion

请帮助我实现这一目标。

在此先感谢。

+0

这是可以做到相当容易以'CURSOR'。 – Johan

+0

@Johan,请提供逻辑 – Nagesh

回答

1

我不喜欢使用游标,但有时却是得心应手。

在这里你去:

-- Test data 
declare @orders table 
    (Order_a varchar(20), 
    Item varchar(20), 
    Product varchar(20), 
    Qty int) 

insert into @orders 
select 'OR-01', 'I-001', 'PRD-01', 70 
union all 
select 'OR-01', 'I-001', 'PRD-02', 15 
union all 
select 'OR-01', 'I-001', 'PRD-03', 55 

-- End test data 

declare @workorders table 
    (Order_a varchar(20), 
    WorkOrd varchar(20), 
    Seq int, 
    Item varchar(20), 
    Product varchar(20), 
    Qty int) 


declare @olq int 
set @olq = 30 

declare @qty_left int 
set @qty_left = @olq 

declare @wo int 
set @wo = 1 

declare @seq int 
set @seq = 1 

declare @Order_a varchar(20) 
    ,@Item varchar(20) 
    ,@Product varchar(20) 
    ,@Qty int 

-- Declare and set the cursor  
declare qtycursor cursor for  
select Order_a 
    ,Item 
    ,Product 
    ,Qty 
from @orders 

open qtycursor  
fetch next from qtycursor into @Order_a, @Item, @Product, @Qty  
while @@fetch_status = 0  
begin  

    while @Qty <> 0 
    begin 
     if @Qty < @qty_left 
     begin 
      insert into @workorders 
      select @Order_a, 'WO-'+CAST(@wo as varchar), @seq, @Item, @Product, @Qty 

      set @seq = @seq + 1 
      set @qty_left = @qty_left - @Qty 
      set @Qty = 0 
     end 
     else 
     begin 
      insert into @workorders 
      select @Order_a, 'WO-'+CAST(@wo as varchar), @seq, @Item, @Product, @qty_left 

      set @Qty = @Qty - @qty_left 
      if @Qty > 0 
      begin 
       set @seq = 1  
      end 
      set @wo = @wo + 1 
      set @qty_left = @olq 

     end 
    end 




fetch next from qtycursor into @Order_a, @Item, @Product, @Qty  
end  
close qtycursor  
deallocate qtycursor  

select * from @workorders 
+0

逻辑非常好,干净。感谢您的努力。 – Nagesh

3

由于项目没有意义,我从SQL中删除它。

declare @t table(order1 varchar(5), product varchar(6), seqcheck int) 

insert @t values('OR-01','PRD-01',70) 
insert @t values('OR-01','PRD-02',15) 
insert @t values('OR-01','PRD-03',55) 

;with 
b as 
(
select order1, product, seqcheck - 30 seqcheck, case when seqcheck > 30 then 30 else seqcheck end quantity, 1 seq, 1 workorder 
from @t 
where product = 'PRD-01' 
union all 
select order1, product, seqcheck - 30, case when seqcheck > 30 then 30 else seqcheck end quantity, 1 seq, workorder + 1 
from b 
where seqcheck > 0 
union all 
select t.order1, t.product, t.seqcheck + b.seqcheck, case when t.seqcheck + b.seqcheck >= 0 then -b.seqcheck else t.seqcheck end quantity, seq + 1, workorder 
from b join @t t on 
cast(stuff(b.product, 1,4, '') as int) = cast(stuff(t.product, 1,4, '') as int) - 1 
where b.seqcheck <= 0 
) 
select order1 [order], 'WO-' + left('000'+ cast(workorder as varchar(4)), 4) workord, right('000'+ cast(seq as varchar(3)), 3) seq, product, quantity from b 
option(MAXRECURSION 0) 

结果:

order workord seq product quantity 
----- ------- ---- ------- ----------- 
OR-01 WO-0001 001 PRD-01 30 
OR-01 WO-0002 001 PRD-01 30 
OR-01 WO-0003 001 PRD-01 10 
OR-01 WO-0003 002 PRD-02 15 
OR-01 WO-0003 003 PRD-03 5 
OR-01 WO-0004 001 PRD-03 30 
OR-01 WO-0005 001 PRD-03 20 
+0

亲爱的@ t-clausen.dk非常感谢您的帮助。它按照我的要求工作。 – Nagesh