2017-03-03 56 views
-1

我正在嘗試做以下事情:我在系統中有用戶活動的表,並且我想根據每個對象上的每個活動的時間創建一系列活動當每個活動之間的時間達到10秒時,併爲每個序列提供一個唯一的ID。SQL根據時間差創建行的順序

例如見下表:

userID ObjectID  Timestamp    
======== ========== ===================== 

     1   52 2016-05-01 19:10:01   
     1   52 2016-05-01 19:10:05   
     1   52 2016-05-01 19:10:07   
     1   52 2016-05-01 19:12:01   
     1   52 2016-05-01 19:12:04   
     2   54 2016-05-01 19:11:09   
     2   54 2016-05-01 19:11:19   
======== ========== ===================== == == 

在這個表上期望的輸出是:

userID ObjectID   Timestamp  seq seqID   
======== ========== ===================== 

     1   52 2016-05-01 19:10:01 1 1 
     1   52 2016-05-01 19:10:05 2 1 
     1   52 2016-05-01 19:10:07 3 1 
     1   52 2016-05-01 19:12:01 1 2 
     1   52 2016-05-01 19:12:04 2 2 
     2   54 2016-05-01 19:11:09 1 3 
     2   54 2016-05-01 19:11:19 2 3 
======== ========== ===================== == == 

我嘗試使用ROW_NUMBER()和DENSE_RANK()函數做到這一點,但我沒有成功以10秒的不同條件來做到這一點。

+0

你爲什麼在這裏標記MySQLi? – DavidG

+0

如果您搜索空白處和島嶼,有相當多的例子。你的標籤也令人困惑,這是關於SQL Server還是MySQL –

+0

修復了標籤,它是關於sql-server – nlan

回答

0

1排序在同一分鐘

DECLARE @test TABLE(UserID INT,ObjectID INT,[Timestamp] DATETIME) 
INSERT INTO @test 
SELECT 1,52,CONVERT(DATETIME,'2016-05-01 19:10:01') UNION ALL 
SELECT 1,52,'2016-05-01 19:10:05' UNION ALL 
SELECT 1,52,'2016-05-01 19:10:07' UNION ALL 
SELECT 1,52,'2016-05-01 19:12:01' UNION ALL 
SELECT 1,52,'2016-05-01 19:12:04' UNION ALL 
SELECT 2,54,'2016-05-01 19:11:09' UNION ALL 
SELECT 2,54,'2016-05-01 19:11:19' 

SELECT * 
    , ROW_NUMBER()OVER(PARTITION BY DATEDIFF(MINUTE,0,Timestamp) ORDER BY [Timestamp]) AS seq 
    , DENSE_RANK()OVER(ORDER BY DATEDIFF(MINUTE,0,Timestamp)) as seqID 
FROM @test 
 
UserID  ObjectID Timestamp    seq     seqID 
----------- ----------- ----------------------- -------------------- -------------------- 
1   52   2016-05-01 19:10:01.000 1     1 
1   52   2016-05-01 19:10:05.000 2     1 
1   52   2016-05-01 19:10:07.000 3     1 
2   54   2016-05-01 19:11:09.000 1     2 
2   54   2016-05-01 19:11:19.000 2     2 
1   52   2016-05-01 19:12:01.000 1     3 
1   52   2016-05-01 19:12:04.000 2     3 

2.我想與你的描述匹配以下。 @test與上面相同。

;with div AS (
     SELECT t.UserID,t.ObjectID,t.Timestamp   
      ,ROW_NUMBER()OVER(ORDER BY t.UserID,t.Timestamp) AS SeqID 
      ,LEAD(t.[Timestamp])OVER(PARTITION BY t.UserID ORDER BY t.Timestamp) AS NextTime 
      ,t.DiffSencond 
     FROM (
      SELECT *,LEAD([Timestamp])OVER(PARTITION BY UserID ORDER BY Timestamp) AS NextTime 
       ,DATEDIFF(SECOND,[Timestamp],LEAD([Timestamp])OVER(PARTITION BY UserID ORDER BY Timestamp)) AS DiffSencond 
     FROM @test 
    ) AS t 
    WHERE t.DiffSencond IS NULL OR t.DiffSencond>10 

    ) 

select *,ROW_NUMBER()OVER(PARTITION BY d.SeqID ORDER BY t.[Timestamp]) AS seq 
from @test as t 
outer apply (select top 1 SeqID from div where div.UserID=t.UserID and datediff(second,t.Timestamp,div.Timestamp)>=0 order by SeqID) d 
 
    UserID ObjectID Timestamp SeqID seq 
1 1 52 01.05.2016 19:10:01 1 1 
2 1 52 01.05.2016 19:10:05 1 2 
3 1 52 01.05.2016 19:10:07 1 3 
4 1 52 01.05.2016 19:12:01 2 1 
5 1 52 01.05.2016 19:12:04 2 2 
6 2 54 01.05.2016 19:11:09 3 1 
7 2 54 01.05.2016 19:11:19 3 2 
0
Select * 
Into #Temp 
From ATable 

Declare 
    @LoopCounter int = 1 
    ,@TimeStamp1 datetime 
    ,@TimeStamp2 datetime 
    ,@Userid1 int 
    ,@ObjectID1 int 
    ,@Userid2 int 
    ,@ObjectID2 int 
    ,@Seq int 
    ,@SeqID int 


While @LoopCounter <= (Select Count(*) From #Temp) 
Begin 
    Select Top 1 
     @TimeStamp1 = TimeStamp 
     ,@Userid1 = UserId 
     ,@ObjectID1 = ObjectID 
     ,@Seq = Seq 
     ,@SeqID = SeqID 
    From #Temp 
    Delete TOP 1 from #Temp 
    Select Top 1 
     @TimeStamp2 = TimeStamp 
     ,@Userid2 = UserId 
     ,@ObjectID2 = ObjectID 

    from #Temp 
    If(
     (@TimeStamp2 - @TimeStamp1) < 10 
     and @Userid2 = @Userid1 
     and @ObjectID2 = @ObjectID1 
     ) 
    Begin 
     Update 
      TableName 
     Set 
      Seq = @Seq + 1 
      ,SeqID = @SeqID 
     Where 
      ObjectID = @ObjectID2 
      and TimeStamp = TimeStamp2 
    End 

    Else 
    Begin 
     Update 
      TableName 
     Set 
      Seq = 1 
      ,SeqID = @SeqID + 1 
     Where 
      ObjectID = @ObjectID2 
      and TimeStamp = @TimeStamp2 
    End 

    @LoopCounter = @LoopCounter + 1 

End 

我想這應該這樣做。如果我在代碼中犯了錯誤,請告訴我。