我有一个关于在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语法。
这有意义吗?有什么想法吗?
提前感谢您的帮助!
答案 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
表示该项目的库存目前仍然耗尽。