2012-06-12 41 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