从统计日志中检测多个/共享登录

时间:2013-09-05 13:59:05

标签: sql sql-server-2008 tsql stored-procedures

我们运营的网站不允许共享登录详细信息,但从未构建系统来阻止这些用户。现在,管理层想要一份正在分享的人的报告。我很确定我们可以通过分析统计数据库找到它们。

我检测共享登录的想法是在每个月末查询统计信息表(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

问题是如何在查询成千上万的条目时有效地做到这一点?

1 个答案:

答案 0 :(得分:2)

注意:我删除了之前的CTE答案,因为我能使其工作的唯一方法是使用SQL 2008上没有的LAG。 ,我想出了一些运行得更快的东西。

以下将数据拆分为两个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的索引。

相关问题