如何查询在一个时间跨度内具有特定计数的记录

时间:2014-07-02 21:38:19

标签: sql sql-server

我有一张表格,其中存储了每个网站请求的日志。每次请求页面时,都会插入一条记录。我现在想分析日志中的数据以检测可能的自动(非人)请求。我需要使用的标准是个人用户在y秒内的x个请求数。

所以,数据看起来像这样:

| 网页 | UserId |的日期 |
| /Page1.htm | 001 | 2014-06-02 11:03 AM |
| /Page2.htm | 001 | 2014-06-02 11:03 AM |
| /Page1.htm | 002 | 2014-06-02 11:04 AM |
| /Page3.htm | 001 | 2014-06-02 11:04 AM |
| /Page2.htm | 002 | 2014-06-02 11:05 AM |
| /Page4.htm | 001 | 2014-06-02 11:05 AM |
| /Page5.htm | 001 | 2014-06-02 11:07 AM |
| /Page3.htm | 002 | 2014-06-02 11:15 AM |

因此,我希望获得在任何5秒的时间内发出5个或更多请求的所有UserID。我怎么能得到它?仅使用SQL就可以实现这一点吗?

我无法访问Web服务器日志或SQL Server数据库以外的任何其他内容。

3 个答案:

答案 0 :(得分:2)

以下是您要查找的查询:

SELECT
    T1.Page, 
    T1.UserId, 
    T1.Date, 
    MIN(T2.Date) AS Date2, 
    DATEDIFF(minute, T1.Date, MIN(T2.Date)) AS DaysDiff,
    COUNT(*) RequestCount
FROM
    [STO24541450] T1 LEFT JOIN [STO24541450] T2
    ON T1.UserId = T2.UserId AND T2.Date > T1.Date
GROUP BY
    T1.Page, T1.UserId, T1.Date
HAVING 
    DATEDIFF(minute, T1.Date, MIN(T2.Date)) >= 5 AND COUNT(*) >= 5;

答案 1 :(得分:0)

我可能会按时间范围和UserId进行分组,并在计数大于5的情况下抓取任何数据。

select count(*),
       UserId,
       dateadd(SECOND, DATEDIFF(SECOND, '01-jan-1970', [date])/5*5, '01-jan-1970') 
from   [LogTable]
group by UserId, DATEDIFF(SECOND, '01-jan-1970', [date])/5
having count(1) > 5

以上将为用户发出超过5个请求的每个时段返回相同的UserId。如果您只对userId感兴趣,而不是他们违反条件的次数或次数,您可以将上述内容简化为

select distinct(UserId)
from   [LogTable]
group by UserId, DATEDIFF(SECOND, '01-jan-1970', [date])/5
having count(1) > 5

答案 2 :(得分:-1)

这是未经测试的,但希望能让您知道如何继续。

SELECT UserId, COUNT(UserId) as AccessCount
     (SELECT UserId FROM AccessLogTable WHERE Date BETWEEN startDate AND endDate) a
GROUP BY UserId HAVING COUNT(UserId) > x

我们在这里做的是使用子查询首先选择感兴趣的记录子集(您的y标准)。然后将其封装在外部查询中,您将通过具有count(userid)>的UserId进行分组。 X