TSQL每日计数?

时间:2011-12-05 17:22:51

标签: tsql date-parsing datepart

我有一个网站,我在点击的每个链接上记录SQL Server 2008数据库中的客户端指标。我已经编写了查询来获取每日总点击次数,但是我想知道用户在给定的时间内点击了多少次(即在5秒内)。

这里的想法是锁定试图抓取内容的传入IP地址。假设如果在5秒内检测到超过5次“点击”或者来自给定IP地址的每日点击次数超过某个值,则表示这是一次抓取尝试。

我尝试过以下几种变体:

-- when a user clicked more than 5 times in 5 seconds
SELECT DATEADD(SECOND, DATEDIFF(SECOND, 0, ClickTimeStamp), 0) as ClickTimeStamp, COUNT(UserClickID) as [Count]
FROM UserClicks
WHERE DATEDIFF(SECOND, 0, ClickTimeStamp) = 5
GROUP BY IPAddress, ClickTimeStamp

这个特别返回以下错误:

  

Msg 535,Level 16,State 0,Line 3 of datediff函数导致   溢出。分隔两个日期/时间的日期部分的数量   实例太大了。尝试使用较不精确的约会   日期部分。

所以再一次,我想使用秒数datepart,我相信我已经走上了正确的轨道,但还是没有完全得到它。

帮助表示感谢。感谢。

- 更新 -

很好的建议,并帮助我认为这种方法是错误的。每次点击都会进行检查。我应该做的是给定时间戳,检查在最后5秒内是否从同一IP地址记录了5次点击。所以它会像是,计算>的点击次数。 GetDate() - 5秒

尝试下面的内容仍然没有给我一个准确的数字。

SELECT COUNT(*)
FROM UserClicks
WHERE ClickTimeStamp >= GetDate() - DATEADD(SECOND, -5, GetDate())

3 个答案:

答案 0 :(得分:1)

希望我的语法很好,我只有oracle来测试它。我将假设您有一个名为user_id的ID列,该列对于该用户是唯一的(是user_click_id?有助于在这些问题中包含表创建语句)

你必须在这个上进行自我加入。逻辑将采取用户点击并加入用户点击userId = userId并且clicktimestamp上的差异在0-5秒之间。然后它从子选择开始计算。

select u1.user_id, u1.clicktimestamp, u2.clicktimestamp
from userclicks uc1
left join user_clicks uc2  
    on u2.userk_id = u1.user_id
    and datediff(second,u1.ClickTimeStamp,u2.ClickTimeStamp) <= 5
    and datediff(second,u1.ClickTimeStamp,u2.ClickTimeStamp) > 0

此select语句应为每个记录提供user_id / clicktimestampe和1行,该记录与同一用户的clicktimestamp之间的距离为0到5秒。现在只需要计算所有user_id,u1.clicktimestamp组合并突出显示5个或更多的组合。采取上述查询并将其转换为子选择并从中提取计数:

select u1.user_id, u1.clicktimestamp, count(1)
from 
(select u1.user_id, u1.clicktimestamp
from userclicks uc1
left join user_clicks uc2  
    on u2.userk_id = u1.user_id
    and datediff(second,u1.ClickTimeStamp,u2.ClickTimeStamp) <= 5
    and datediff(second,u1.ClickTimeStamp,u2.ClickTimeStamp) > 0) a
group by u1.user_id, u1.clicktimestamp
having count(1) >= 5

希望我能在MS机器上验证我的语法......那里可能会有一些拼写错误,但逻辑应该是好的。

答案 1 :(得分:0)

假设只为当前活动输入了日志条目 - 也就是说,无论何时插入新行,记录的时间都是针对该时间点的,而且从来没有任何先前的时间点 - 那么您只需要查看一段时间内的数据,而不必像现在一样审查“所有数据”。

接下来的问题是:您多久检查一次?如果您关注每秒点击次数,那么“每小时一次”和“每24小时一次”之间的某种情况似乎是合理的。

接下来:定义您的间隔。 “5秒内每个IPAddress的所有点击次数”可以有两种方式:设置窗口(00-04,05-09,10-14等)或滑动窗口(00-04,01-05,02-06等)。 )可能与5秒窗口无关,但可能更长时间(每天“点击次数”)更相关。

有了这个,我采取的一般方法是:

  • 从您关心的最早时间点开始(1小时前,24小时前)
  • 设置“桶”,表示可以识别时间窗口(00:00:00 - 00:00:04,00:00:05 - 00:00:09等)。这可以作为临时表来完成。
  • 对于所有事件,计算自最早点以来经过的秒数
  • 对于每个存储桶,计算达到该存储桶的事件数,按IPAddress(inner join on the temp table on seconds between lowValue and highValue)分组
  • 确定那些超过您的门槛(having count(*) > X)的人,然后对其进行篡改。

答案 2 :(得分:0)

您的更新答案:问题出在

的第三行
SELECT COUNT(*)
 FROM UserClicks
 WHERE ClickTimeStamp >= GetDate() - DATEADD(SECOND, -5, GetDate()) 

GetDate() - DATEADD(SECOND, -5, GetDate())说“取当前日期时间并减去(当前日期时间减去5秒)”。我不完全确定它产生了什么样的价值,但它不会是你想要的那个。

你仍然需要某种时间段,像这样的perah:

SELECT count(*)
 from UserClicks
 where IPAddress = @IPAddress
  and ClickTimeStamp between getdate() and dateadd(second, -5, getdate())

我在使用getdate()时有点不舒服 - 如果你有一个特定的日期时间值(精确到秒),你应该使用它。