SQL中的库存计数

时间:2015-01-30 20:50:19

标签: sql sql-server sql-server-2008-r2

我有一个关于在SQL Server 2008R2中使用T-SQL计算sock out天数的问题。所以基本上我需要一个有一个项目的表,项目从库存中耗尽的日期,以及项目补充的日期。我工作的原始表与此类似

Item_Number | Inv_date_Change | QTY | Inventory_Change_Count
------------|-----------------|-----|-----------------------
    A1      |  2014-01-10     | 10  |  1
    A1      |  2014-01-09     | 0   |  2
    A1      |  2014-01-05     | -1  |  3
    A1      |  2014-01-03     | 10  |  4
    A1      |  2014-01-01     | 0   |  5
    B2      |  2014-01-10     | 5   |  1
    B2      |  2014-01-09     | 0   |  2
    B2      |  2014-01-05     | 1   |  2

请注意,Inv_date_Change列是该项目的广告资源更改日期。我已将Inventory_Change_Count列添加为项目广告资源更改量的计数器。

另请注意,即使数量已用尽(0或小于0),商品库存也会发生变化

我正在寻找的最终产品是这样的:

Item_Number | Date_Exhausted | Date_Replenished
------------|----------------|-----------------
     A1     |   2014-01-05   |  2014-01-10     
     A1     |   2014-01-01   |  2014-01-03     
     B2     |   2014-01-09   |  2014-01-10     

我尝试使用类似于此的查询,使用Inventory_Change_Count列将该表重新连接到自身,作为选择项目耗尽时间的方法:

SELECT *
FROM Inventory a
LEFT JOIN Inventory b ON a.ITEMNMBR = b.ITEMNMBR AND a.LOCNCODE = b.LOCNCODE
        AND ((a.DTE_OUT = b.DTE_OUT - 1) 
                AND a.QTY > 0 
                AND b.QTY < 1)
        WHERE b.QTY IS NOT NULL

我遇到此查询时遇到的问题是,项目A1的第一个实例在2014-01-05而不是2014-01-09已用尽,就像此查询将返回一样。

我还在考虑添加逻辑以查看下一个Inventory_Change_Count up是正数的想法,然后加入Inventory_Change_Count - 1(行中第一次出现负数)。如下所示:

加入a.QTY = b.qty&gt; = 1和b.Inventory_Change_Count&gt; a.Inventory_Change_Count然后a.Inventory_Change_Count - 1 o

但我不知道执行此操作的确切SQL语法。

这有意义吗?有什么想法吗?

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

select a.Item_number,a.Inv_date_Change,b.Inv_date_Change 
from Inventory a join Inventory b on a.Item_number = b.Item_Number and b.Inv_date_Change > a.Inv_date_Change 
where a.QTY <= 0 and b.QTY > 0
and not exists(select * from Inventory d where d.QTY > 0 and d.Item_Number = a.Item_Number and d.Inv_date_Change > a.Inv_date_Change and d.Inv_date_Change < b.Inv_date_Change)
and isnull((select top 1 d.QTY from Inventory d where d.Item_Number = a.Item_Number and d.Inv_date_Change < a.Inv_date_Change order by d.Inv_date_Change desc), 1) > 0

答案 1 :(得分:0)

这是通过相对简单的自联接完成的。问题在于原始数据中的“噪音” - 任何具有耗尽数量的行都会紧接着另一行,并且还有耗尽的数量(当然,按时间顺序)。因此,第一步提供没有这些行的结果集。

然后是干净数据的自联接。在A面,您将拥有qty <= 0的所有行。在B面,您需要具有正qty的行和A侧日期之后的最新日期。

with
Noise( Item_Number, Inv_date_Change, QTY )as(
    -- Select which rows are "noise." Noise is an exhausted row
    -- immediately preceded by another exhausted row.
    select  a.*
    from    Inventory a
    join    Inventory b
        on  b.Item_Number = a.Item_Number
        and b.Inv_date_Change =(
            select  Max( Inv_date_Change )
            from    Inventory
            where   Item_Number = a.Item_Number
                and Inv_date_Change < a.Inv_date_Change )
    where   a.qty <= 0
        and b.qty <= 0
),
Clean( Item_Number, Inv_date_Change, QTY )as(
    -- Now provide the noise-free data.
    select  r.*
    from    Inventory     r
    left join Noise n
        on  n.Item_Number = r.Item_Number
        and n.Inv_date_Change = r.Inv_date_Change
    where   n.Item_Number is null
)
select  a.Item_Number,
        a.Inv_date_Change as Date_Exhausted,
        b.Inv_date_Change as Date_Replenished
from    Clean a
join    Clean b
    on  b.Item_Number = a.Item_Number  -- Has to be the same item
    and b.Inv_date_Change =(           -- with...
        select  Min( Inv_date_Change ) -- most recent date
        from    Clean
        where   Item_Number = a.Item_Number
            and Qty > 0                               -- with non-zero quantity
            and Inv_date_Change > a.Inv_date_Change ) -- after exhaustion date
where   a.qty <= 0  -- And this is exhaustion
order by a.Item_Number, a.Inv_date_Change desc;

我接着问的问题是一个已经用尽但尚未补充的物品。正如您在我的 Fiddle 中看到的那样,我添加了一条数据线来表示这种情况。只需将最终连接更改为左连接即可解决此问题。因此,null字段中的Date_Replenished表示该项目的库存目前仍然耗尽。