2013-06-01 15 views
4

我現在有訪問日誌的表看起來像這樣計數的重複發生後一段時間或基於次級柱

LogID UserID BuildingID Date/Time 
=========================================== 
1  1  1   2013-01-01 10:00 
2  2  1   2013-01-01 10:00 
3  3  1   2013-01-01 10:30 
4  3  2   2013-01-01 11:00 
5  2  1   2013-01-01 11:00 
6  4  1   2013-01-01 11:30 
7  5  1   2013-01-01 11:30 
8  5  1   2013-01-01 11:31 
9  1  3   2013-01-01 12:00 
10  1  3   2013-01-01 12:03 
11  1  2   2013-01-01 12:05 

我需要做的就是創建一個查詢計算的基於重複的用戶記錄數量在以下2個條件:比X分鐘

  1. 的時間差更大的 - X將一個參數由用戶
  2. OR每個不同的建築物爲AU指定SER

例如,如果我設置的時間差是5分鐘,然後我的結果將是:

UserID AccessCount 
==================== 
1  3   <-- +1 for timediff (ID 1,10) +1 for building (ID 11) 
2  2   <-- +1 for timediff (ID 2,5) 
3  2   <-- +1 for building (ID 3,4) 
4  1 
5  1   <-- duplicate ignored because DateDiff < 5min 

希望這是有道理的。

給予一定的背景,這是刷卡進入我們的一些建築物和業務需求的下來了一些分析安全報告。實質上,我們希望檢查給定時間段內的重複訪問(通常在週末進行),但需要考慮到某些滑動點失敗並需要用戶多次滑動的事實。這就是爲什麼我要將datediff作爲滑動錯誤的原因通常意味着用戶會在很短的時間內刷多次。

任何幫助是極大的讚賞,在此先感謝!

+0

SQL不能「跨行」工作 - 它在行本身內優化。你將不得不做一些非常時髦的連接和聚合來實現它。相反,我建議您創建一個遍歷表的作業並創建一個包含所需字段的新表,例如, 'TimeSincePreviousAttempt'。然後,該作業只需遞增地抓取給定的LogID尚未設置「TimeSince ...」的地方。 –

回答

3

你可以當你算一排的思維改寫你的邏輯和不計行。當它位於同一建築物上並且在同一建築物的前一個日期時間的某個時間段內時,您不會計算出一排。

我想這可能是你想要什麼:

select userId, count(*) 
from (select LogID, UserID, BuildingID, dt, 
      lag(dt) over (partition by userid, buildingid) as prevdt 
     from t 
    ) t 
where dt > prevdt + TIMEDIFF or prevdt is NULL 

在SQL中,一個常數添加到日期時間被解釋爲天數。所以,5分鐘將是(5.0/60)/24

您的數據沒有例子,但如果你有三行:

1 1 1 11:30 
2 1 2 11:31 
3 1 1 11:32 

那麼這將不計,因爲第1行是由第一個條件涵蓋三連勝。

+0

謝謝,這正是我所需要的,似乎適用於我所有的測試用例。 – Nathan

+0

@Nathan。 。 。很高興我能夠提供幫助。 –

0

這裏有一個辦法:

declare @duplicateMinutes int = 5 

select UserID, AccessCount = count(1) 
from AccessLogs a 
where not exists 
    (
    select 1 
    from AccessLogs d 
    where a.LogID < d.LogID -- add this to try and avoid duplicate times cancelling each other 
     and a.UserID = d.UserID 
     and a.BuildingID = d.BuildingID 
     and a.SwipeTime >= dateadd(mi, [email protected], d.SwipeTime) 
     and a.SwipeTime <= d.SwipeTime 
) 
group by UserID 
order by UserID 

SQL Fiddle with demo - 可爲您的數據的預期結果。