Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在每次输入的一分钟内通过联系查找20个或更多的输入_Sql_Sql Server - Fatal编程技术网

Sql 在每次输入的一分钟内通过联系查找20个或更多的输入

Sql 在每次输入的一分钟内通过联系查找20个或更多的输入,sql,sql-server,Sql,Sql Server,我们正在收集联系人及其访问的每个页面的一些分析数据。很多分析数据来自恶意攻击或机器人程序,所以他们在不到一分钟的时间内就访问了网站的20多个页面。我希望能够每天清除一次这些数据,但我不知道如何编写SQL查询,以选择联系人在一分钟内访问超过20页的所有行,而不仅仅是过去一分钟,而是一整天。我将如何编写查询以获取某个联系人的活动行,该联系人在一分钟内拥有20多个活动组 分析表包含DateCreated、ContactID、ActivityName和ActivityUrl 样本数据(假设一分钟内超过5

我们正在收集联系人及其访问的每个页面的一些分析数据。很多分析数据来自恶意攻击或机器人程序,所以他们在不到一分钟的时间内就访问了网站的20多个页面。我希望能够每天清除一次这些数据,但我不知道如何编写SQL查询,以选择联系人在一分钟内访问超过20页的所有行,而不仅仅是过去一分钟,而是一整天。我将如何编写查询以获取某个联系人的活动行,该联系人在一分钟内拥有20多个活动组

分析表包含DateCreated、ContactID、ActivityName和ActivityUrl

样本数据(假设一分钟内超过5个):

所需数据:

2020-07-25 23:59:58, 78, Page visit, /home  
2020-07-25 23:59:57, 78, Page visit, /home/1  
2020-07-25 23:59:56, 78, Page visit, /home/3  
2020-07-25 23:59:55, 78, Page visit, /home/4   
2020-07-25 23:59:52, 78, Page visit, /home/5  
2020-07-25 23:59:51, 78, Page visit, /home/6  
对于以下数据:

n, d
John, 2020-01-01 00:00:10
John, 2020-01-01 00:00:30
John, 2020-01-01 00:00:50
John, 2020-01-01 00:01:10
John, 2020-01-01 00:01:30
John, 2020-01-01 00:01:50
您可以根据日期的原始分钟精度进行分组;这可能就足够了:

SELECT n, DATEDIFF(minute, CAST(d as date), d) 
FROM t
GROUP BY n, DATEDIFF(minute, CAST(d as date), d) 
HAVING COUNT(*) > 20
当然,你可能会遇到这样的人,他在一分钟内提出20个请求,这样每分钟就有一半的请求被拒绝。你可以通过增加30秒的时间并合并这两个查询来解决这个问题

您还可以执行其他操作,例如通过协调查询,在过去一分钟内回过头来查找同一分钟滑动窗口中的行数:

SELECT 
  n, 
  (SELECT COUNT(*) FROM t tI WHERE tI.n = tO.n AND tI.d BETWEEN DATEADD(minute, -1, tO.d) AND tO.d) ct
FROM 
  t tO
然后,可以通过n的MAX(ct)>20来查询
组的此结果集


脚注:很遗憾,SQLS不支持像Oracle那样在其窗口函数中设置日期范围<代码>计数(*)超过(间隔1分钟之前和0之间按n顺序按d范围划分)
-SQLS了解范围,但仅适用于“与当前行具有相同值的行之前/之后/两者”而且我不相信有什么方法可以调整你的连续可变的日期时间,使其适用于使用
lag()
,你可以在一分钟内获得访问了20页的联系人:


也就是说,如果回顾19行,一分钟内有20行,而该行距离当前行不到一分钟。

请提供示例数据和所需结果。并提出问题;您在这里没有提出任何问题。请向我们展示您的尝试-因此这不是免费的代码编写服务。
SELECT 
  n, 
  (SELECT COUNT(*) FROM t tI WHERE tI.n = tO.n AND tI.d BETWEEN DATEADD(minute, -1, tO.d) AND tO.d) ct
FROM 
  t tO
select distinct contactid
from (select t.*,
             lag(datecreated, 19) over (partition by contactid order by datecreated) as lag20
      from t
     ) t
where lag20 > dateadd(minute, -1, datecreated);