TSQL的每日计数?

TSQL的每日计数?,tsql,date-parsing,datepart,Tsql,Date Parsing,Datepart,我有一个网站,在这里,我在每一个点击的链接上都在SQLServer2008DB中记录客户机指标。我已经编写了查询来获取每日总点击量,但是我想知道用户在给定的时间跨度内(即5秒内)点击了多少次 这里的想法是锁定试图抓取内容的传入IP地址。假设在5秒内检测到5次以上的“点击”,或者给定IP地址的每日点击次数超过某个值,则这是一次刮取尝试 我尝试了以下几种变体: -- when a user clicked more than 5 times in 5 seconds SELECT DATEADD(S

我有一个网站,在这里,我在每一个点击的链接上都在SQLServer2008DB中记录客户机指标。我已经编写了查询来获取每日总点击量,但是我想知道用户在给定的时间跨度内(即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,16级,状态0,第3行datediff函数导致 溢流。分隔两个日期/时间的日期部分数 实例太大。尝试使用datediff,但不太精确 日期部分

所以再一次,我想使用seconds datepart,我相信我在正确的轨道上,但没有完全理解它

谢谢你的帮助。谢谢

--更新--

伟大的建议,帮助我认为这种方法是错误的。每次点击都会进行检查。我应该做的是,对于给定的时间戳,检查是否在最后5秒钟内从同一IP地址记录了5次单击。因此,计算>GetDate()-5秒的点击次数

尝试下面的方法仍然不能给我一个准确的数字

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

假设只为当前活动输入日志条目——也就是说,无论何时插入新行,记录的时间都是该时间点的,而不是之前的任何时间点——那么您应该只需要在设定的时间段内查看数据,而不必像现在这样查看“所有数据”

下一个问题是:你多久检查一次?如果你关心的是每秒点击次数,那么“每小时一次”和“每24小时一次”之间的一些东西似乎是合理的

下一步:定义你的时间间隔。“5秒钟内每个IP地址的所有点击”可能有两种方式:设置窗口(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等)。这可以作为临时表来完成
  • 对于所有事件,计算自最早时间点起经过的秒数
  • 对于每个bucket,计算命中该bucket的事件数,并按IPAddress分组(
    在lowValue和highValue之间的秒数内临时表上的内部联接)
  • 识别那些超过您的阈值(
    having count(*)>X
    ),并对其进行防御

假设只为当前活动输入日志条目——也就是说,每当插入新行时,记录的时间是该时间点的,而不是之前的任何时间点——那么您应该只需要在设定的时间段内查看数据,而不必像现在这样查看“所有数据”

下一个问题是:你多久检查一次?如果你关心的是每秒点击次数,那么“每小时一次”和“每24小时一次”之间的一些东西似乎是合理的

下一步:定义你的时间间隔。“5秒钟内每个IP地址的所有点击”可能有两种方式:设置窗口(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等)。这可以作为临时表来完成
  • 对于所有事件,计算自最早时间点起经过的秒数
  • 对于每个bucket,计算命中该bucket的事件数,并按IPAddress分组(
    在lowValue和highValue之间的秒数内临时表上的内部联接)
  • 识别那些超过您的阈值(
    having count(*)>X
    ),并对其进行防御

    • 希望我的语法是好的,我只有oracle来测试这个。我假设您有一个名为user\u ID的ID列,它是该用户所独有的(是user\u click\u ID吗?如果可以,在这些问题中包含table create语句会很有帮助)

      你必须在这一个上进行自连接。逻辑是将userclick和join连接到userclick on 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
      
      选择u1.user\u id,u1.clicktimestamp,u2.clicktimestamp
      从用户点击uc1
      左加入用户\单击uc2
      在u2.userk\u id=u1.user\u id上
      和datediff(秒,u1.单击时间戳,u2.单击时间戳)0
      
      此select语句应为您提供用户id/clicktimestamp,并为与同一用户的clicktimestamp相隔0到5秒的每条记录提供1行。现在只需计算所有用户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
      
      选择u1.user\u id,u1.clicktimestamp,count(1)
      从…起
      (选择u1.user\u id,u1.clicktimestamp
      从用户点击uc1
      左加入用户\单击uc2
      在u2.userk\u id=u1.user\u id上
      和datediff(秒,u1.单击时间戳,u2.单击时间戳)0)a
      按u1.user\U id分组,u1.clicktimestamp
      计数(1)>=5
      
      希望我能在MS机器上验证我的语法…可能有一些打字错误,但逻辑应该是好的

      H
      SELECT COUNT(*)
       FROM UserClicks
       WHERE ClickTimeStamp >= GetDate() - DATEADD(SECOND, -5, GetDate()) 
      
      SELECT count(*)
       from UserClicks
       where IPAddress = @IPAddress
        and ClickTimeStamp between getdate() and dateadd(second, -5, getdate())