2012-06-12 40 views
0

我有记录何时将某些项目发送或返回到特定位置的表,并且我想要计算每次返回特定项目之间的时间间隔。SQL计算日志中出现次数之间的差距

的样本数据:

Item ReturnDate: 
Item1, 20120101 
Item1, 20120201 
Item1, 20120301 
Item2, 20120401 
Item2, 20120601 

所以在这种情况下,我们可以看到有一个个月的空白,直到第1项是返回的第一次,再过一个月就返回第二个时间之前。第2项在2个月后回来。

我的出发点是:

Select r1.Item, r1.ReturnDate, r2.Item, r2.ReturnDate, DateDiff(m, r1.ReturnDate, r2.ReturnDate) 
from Returns r1 
inner join Returns r2 on r2.VehicleNo = r1.VehicleNo 

然而,在此示例中,每个项目相比,它已归还所有其他实例 - 而不仅仅是下一个。所以我需要限制这个查询,所以它只会比较相邻的回报。

一种解决方案是Tag与计数每次退货(该项目已返回的次数):

Item ReturnDate, ReturnNo: 
Item1, 20120101, 1 
Item1, 20120201, 2 
Item1, 20120301, 3 
Item2, 20120401, 1 
Item2, 20120601, 2 

这将使我使用下面的T-SQL(或类似):

Select r1.Item, r1.ReturnDate, r2.Item, r2.ReturnDate, DateDiff(m, r1.ReturnDate, r2.ReturnDate) 
from Returns r1 
inner join Returns r2 on r2.VehicleNo = r1.VehicleNo 
and (r1.ReturnNo + 1 = r2.ReturnNo) 

我的第一个问题是,这是一种合理的/最佳的方法,还是有更好的方法?其次,计算ReturnNo的最简单/最灵活的方法是什么?

+0

你能告诉我们有一点关于你的餐桌结构?你需要其他东西的返回号码吗? –

+0

@NicoleCastle我试图保持解释的一般性,而不是提供更具体和更少帮助的术语的实时DDL。假设有一张表格记录外部物品(通常是客户)的物品接收情况,我们希望分析每次收到相同物品之间的时间间隔。 Item和ReturnDate在这种情况下都是相关的。 – CJM

+0

@NicoleCastle ...并且不,我不需要返回任何东西 - 这只是帮助我比较每件物品的下一个回报。 – CJM

回答

3

如果您正在使用SQL Server 2005+,使用ROW_NUMBER()做你想要什么:

WITH RankedReturn AS 
(
    SELECT Item, ReturnDate, 
    ROW_NUMBER() OVER (PARTITION BY Item ORDER BY ReturnDate DESC) AS ReturnNo 
    FROM Returns 
) 
SELECT * FROM RankedReturn 

显然,现在你有你的CTE你可以把任何你在外部SELECT需要。我会用外申请此项:

WITH RankedReturn AS 
(
    SELECT Item, ReturnDate, 
    ROW_NUMBER() OVER (PARTITION BY Item ORDER BY ReturnDate DESC) AS ReturnNo 
    FROM Returns 
) 
SELECT rOuter.Item, rOuter.ReturnDate, DATEDIFF(month, prev.PrevDate, ReturnDate) AS Months 
FROM RankedReturn rOuter 
OUTER APPLY 
    (
    SELECT ReturnDate AS PrevDate 
    FROM RankedReturn rInner 
    WHERE rOuter.Item = rInner.Item AND rOuter.ReturnNo = rInner.ReturnNo - 1 
) prev 

哎呀,和SQL Fiddle is here

编辑是因为月差计算倒退;现在固定

1

这是我会怎么做:

select itemNo, 
     dt, 
     DATEDIFF(day, previousDt, dt) as daysSince 
from (select itemNo, 
       dt, 
       (select top 1 dt from testTable where itemNo = outerTbl.itemNo and dt < outerTbl.dt order by dt desc) as previousDt 
     from testTable as outerTbl 
     ) as x 

...这是任何人有点设置代码测试的其他解决这一

create table testTable(
itemNo nvarchar(20), 
dt datetime) 
go 

insert into testTable values('Item1', '2012-01-01'); 
insert into testTable values('Item1', '2012-02-01'); 
insert into testTable values('Item1', '2012-03-01'); 
insert into testTable values('Item2', '2012-04-01'); 
insert into testTable values('Item2', '2012-05-01'); 
go 
+1

对于我以前发布的Generic DDL的+1。 – CJM