根据行上的先前值减少字段值

时间:2014-10-02 16:28:26

标签: sql sql-server-2008 tsql

我有一张这样的表:

Order Number  ItemCode   Quantity_Ordered   AvailableInShop
-----------------------------------------------------------
1             10         3                  3
2             10         2                  3 

但我需要一个查询来获得此输出:

Order Number  ItemCode   Quantity_Ordered   AvailableInShop
-----------------------------------------------------------
1             10         3                  3
2             10         2                  0

这是因为第一个销售订单已经为后续销售订单支付了所有数量。

这是我试过的

select 
  [order number], 
  itemcode, 
  quantity_ordered, 
  availableInshop, 
  Row_Number() over (partition itemcode order by [order number] asc) Rownumber  
from Orders

2 个答案:

答案 0 :(得分:0)

谢谢你我最终做的动机如下;

DECLARE @Orders TABLE
            (
                DocEntry bigint,  DocDate datetime,  [Customer_Name] nvarchar(max),Itemcode nvarchar(50), [Order_Number] nvarchar(max)
                ,Quantity int, OnHand int ,RowNumber int
            );

            INSERT INTO @Orders
            select O.DocEntry,  o.DocDate,CardName,r.itemcode, o.NumAtCard [Order_Number], r.Quantity, 
            OnHand- (select sum(quantity) from rdr1 with (nolock)  where itemcode= r.itemcode and linestatus='o' and pickidNo is not null) OnHand
            , ROW_NUMBER() over (partition by r.itemcode 
                                                                                        order by o.docentry asc)
            from ORDR o join RDR1 r on o.DocEntry = r.DocEntry
            inner join OITW W with (nolock) on r.ItemCode=W.ItemCode and W.WhsCode=r.WhsCode  where 
          r.ItemCode ='1034356' and o.docstatus='o' and canceled='n' and r.pickidno is null
            order by 1          ;

             with mother as(  --cte produces unused_onhand
             select *, 

             case when (select top 1 OnHand -Quantity from @orders where RowNumber= r.RowNumber-1 and Itemcode=r.Itemcode )
             IS NUll 
             then r.OnHand --- for first row value append onHand
             else
             (select top 1 OnHand - ( select SUM(quantity ) from @Orders where Itemcode=r.Itemcode and RowNumber < r.RowNumber    ) from @orders where RowNumber= r.RowNumber-1 and Itemcode=r.Itemcode )
             end Unused_OnHand -- for subsequent onhand, append unused_onhand
             from @Orders r
             )  
             select *,           
             CASE when  (CAST( CAST( Unused_OnHand as  NUmeric(18,3)) / CAST( Quantity as  NUmeric(18,3) ) as NUmeric(18,3)) *100 ) > 100
                then CAST (100.00 AS numeric(18,3))

                when (CAST( CAST( Unused_OnHand as  NUmeric(18,3)) / CAST( Quantity as  NUmeric(18,3) ) as NUmeric(18,3)) *100 ) < 0
                then 0
                else
                (CAST( CAST( Unused_OnHand as  NUmeric(18,3)) / CAST( Quantity as  NUmeric(18,3) ) as NUmeric(18,3)) *100 ) 
                end[Fulfillment%] 
             from mother

答案 1 :(得分:0)

假设我已正确理解您的问题,并且您有一个支持LAG和FIRST_VALUE函数的SQL Server版本,那么下面的T-SQL是一种可能的方式来做您想要的:

with myCte as 
(
    select o.oNum, o.itemCode, o.qOrdered, 
        sum(o.qOrdered) over (partition by o.itemCode order by o.oNum asc rows between unbounded preceding and current row) as totalOrdered,
        FIRST_VALUE(o.qAvailable) over (partition by o.itemCode order by o.oNum asc) as initialAvailability
    from dbo.Orders as o
),

myCte2 as
(
    select *, case when m.initialAvailability-m.totalOrdered < 0 then 0 else m.initialAvailability-m.totalOrdered end as nextAvailability
    from myCte as m
),

myCte3 as
(
    select *,
        lag(m.nextAvailability) over (partition by m.itemCode order by m.oNum asc) as prevAvailability
    from myCte2 as m
)

select m.oNum, m.itemCode, m.qOrdered, case when m.prevAvailability is null then m.initialAvailability else m.prevAvailability end as qAvailable
from myCte3 as m

当然,我同意其他人的观点,即不将可用性存储在与订单数量相同的记录中,这将是一种更明智的长期方法。