我有一个网站,我在点击的每个链接上记录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())
答案 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秒窗口无关,但可能更长时间(每天“点击次数”)更相关。
有了这个,我采取的一般方法是:
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()时有点不舒服 - 如果你有一个特定的日期时间值(精确到秒),你应该使用它。