2012-04-05 106 views
3

我有一組具有時間戳的user_id的登錄數據。如何在sql server中相隔一個小時挑選記錄

用戶可以多次登錄,但我們需要從最少記錄開始至少相隔一小時返回記錄。該刪除必須發生在用戶級別(可以有多個用戶)

例如,

  • USER1 2012-03-07 14:24:30.000
  • USER1 2012-03-07 14:34:30.000
  • USER1 2012-03-07 15:14:30.000
  • USER1 2012 -03-07 15:20:30.000
  • USER1 2012-03-07 15:30:30.000
  • USER1 2012-03-08 09:20:30.000
  • USER1 2012-03-08 9時50: 30.000
  • user1 2012-03- 08 10:30:30.000
  • 用戶2 2012-03-07 15:20:30.000

我只希望看到以下記錄

  • USER1 2012-03-07 14:24 :30.000
  • USER1 2012-03-07 15:30:30.000
  • USER1 2012-03-08 09:20:30.000
  • USER1 2012-03-08 10:30:30.000
  • USER2 2012-03-07 15:20:30.000

================================== ======================================

有沒有辦法做到這一點一個乾淨的方式?我們可以遞歸地做到這一點,但我希望有可能通過使用row_number分區。

任何幫助非常感謝!

+0

什麼版本的sql server? – Glenn 2012-04-05 23:21:07

回答

3

在Sql Server 2005或更新版本中,此CTE將返回LoginAt日期時間表,將已經選擇的LoginAts之外的時間除去小於1小時的表。

;with SkipHour(UserID, LoginAT, rn) as (
    select UserID, min(LoginAt), cast (1 as bigint) 
    from LogTable 
    group by UserID 
    union all 
    select SkipHour.UserID, LogTable.LoginAt, 
     row_number() over (partition by SkipHour.UserID 
          order by Logtable.LoginAt) rn 
    from SkipHour 
    inner join LogTable 
     on LogTable.UserID = SkipHour.UserID 
    where datediff(minute, SkipHour.LoginAt, LogTable.LoginAt) >= 60 
    -- Only first rows from previous generation qualify to have children 
     and rn = 1 
) 
select * 
from SkipHour 
where rn = 1 
order by UserID, LoginAT 

關鍵部分是row_number()。由於Sql Server不允許聚集函數和頂級謂詞,因此row_number()是唯一的方法(IMO)來訂購loginAt日期時間並僅保留第一個日期時間。

Sql Fiddle playground is this way

UPDATE

行數都是適用於每一代獨立。從WITH common_table_expression (Transact-SQL)提取:

分析和聚合函數在CTE的遞歸部分被 施加到該組當前遞歸層次,而不是該組 爲CTE。諸如ROW_NUMBER之類的函數僅對當前遞歸級別傳遞給它們的數據的子集 進行操作,而不是對CTE的遞歸部分遞增的整個 數據集合進行操作。有關更多 信息,請參閱J.在遞歸CTE中使用分析函數。

+0

嘿尼古拉!謝謝一堆!這很好。你可以向我解釋當基本記錄的時間大於一小時時,重新開始編號的分區是如何的? 例如。 該cte獲取每個用戶的最小條目。然後我們根據大於cte記錄的時間條目加入主表。然後它分配row_numbers。是什麼讓row_number重新啓動一個特定的用戶ID? 所以從cte的min入口是10.30上午 ,我們現在加入到上午11點31分,上午11點35分,上午11點40分(它分別獲得行號1,2和3),但是對於12:10 PM,是什麼讓row_number開始回到1?) – user1316437 2012-04-06 15:44:05

+0

@ user1316437請看看我更新的答案。 – 2012-04-06 18:02:26

相關問題