2013-09-05 65 views
1

我們運行的網站不允許共享登錄詳細信息,但系統從未構建以防止這些用戶。現在管理層想要分享那些人的報告。我很確定我們可以通過分析我們的統計數據庫找到他們。從統計日誌中檢測多個/共享登錄

我的檢測共享登錄的想法是在每月月底查詢統計表(MSSQL 2008)並生成一個嫌疑犯名單。要捕捉它們,我需要一個查詢來顯示「切換」會話/ ipaddress。

例如,下面是允許的:

DateTime, UserId, SessionId, IpAddress 
12Feb13 16:30, 10, ABC, x.x.x.x 
12Feb13 16:32, 10, ABC, x.x.x.x 
12Feb13 16:34, 10, DEF, y.y.y.y 
12Feb13 16:36, 10, DEF, y.y.y.y 

以下是允許:

DateTime, UserId, SessionId, IpAddress 
12Feb13 16:30, 10, ABC, x.x.x.x 
12Feb13 16:32, 10, DEF, y.y.y.y 
12Feb13 16:34, 10, ABC, x.x.x.x 
12Feb13 16:36, 10, DEF, y.y.y.y 

的問題是,如何查詢條目成千上萬時有效地做到這一點?

回答

2

注:我刪除我之前CTE答案,因爲我可以使它工作的唯一方法是通過使用LAG這不適用於SQL 2008年儘管如此,我想出了運行速度更快一些。

以下內容將數據拆分爲兩個CTE,第一個返回用戶發生sessionID的時間範圍,第二個返回IP地址的範圍。如果一個會話在一個IP地址範圍內開始,但在該範圍之外完成,那麼該會話必須是不同IP地址的一部分。同樣,如果一個會話在一個IP之前開始,但在一個IP內完成,那麼它也是不好的。

該解決方案假定每個用戶只能使用一次sessionID - 一旦他們的會話結束了一個IP,該ID號就不能在以後使用。

SELECT s.UserId, s.SessionId, s.IpAddress, i.IpAddress, s.MinDate [sMin], s.MaxDate [sMax], 
    i.MinDate [iMin], i.MaxDate [iMax] 
FROM (

    SELECT UserID, SessionID, IPAddress, MIN(DT) MinDate, MAX(DT) MaxDate 
    FROM #USERLOG 
    GROUP BY UserID, SessionID, IPAddress 

) AS s 
INNER JOIN (
    SELECT UserID, IPAddress, MIN(DT) MinDate, MAX(DT) MaxDate 
    FROM #USERLOG ipLog 
    GROUP BY UserID, IPAddress 
) AS i ON 
    s.UserID = i.UserID 
    AND s.IpAddress != i.IpAddress 
    AND (
     (s.MinDate < i.MaxDate AND s.MaxDate > i.MaxDate) OR 
     (s.MinDate < i.MinDate AND s.MaxDate > i.MinDate)) 

爲了獲得最佳性能,你需要爲UserID, Session, IPAddressUserID, SessionID指標。

+1

老兄,我不得不在工作,但我知道我明白了。 –

+0

你先生,是一名高手! – Talon