为postgresql中的每条记录选择接下来的24小时

时间:2016-06-20 11:02:38

标签: postgresql time group-by

我的表格如下:

| Attackerip | timestamp |

现在我想检查每个IP首次尝试每24小时尝试的次数。我希望在这个时间段内尝试的结果少于5次。

例如:攻击者 A 已于23.05.2016 03:00 PM发起攻击,现在查询应该从该尝试开始选择接下来的24小时,并检查 A 是否有在此期间尝试了5次以上。如果 A 确实已经这样做了,我想要返回 A 的Ip,时间跨度(如果可能的话)和尝试次数。

SELECT table1.attackerip, table1.stamp::date, count(*) 
FROM thesislog_v2 table1 INNER JOIN thesislog_v2 table2 
ON table1.attackerip = table2.attackerip AND table2.stamp <= table1.stamp 
AND table2.stamp >= table1.stamp -  interval '24 hours' 
GROUP BY table1.stamp::date, table1.attackerip HAVING COUNT(*) <=5       
ORDER BY table1.attackerip asc

我不确定这个查询是否符合我的想法,因为我不知道GROUP BY如何运行。我认为它还包括一个结果,其中攻击者在这一天有5次尝试而不仅仅是在24小时内。

此外,如果有可能排除上次尝试与下一次尝试之间的时间间隔小于24小时的所有记录,那将是很好的。但我认为这甚至不可能。例如,在24小时的时间内,总共有5次尝试。在该时间跨度的最后一次尝试之后,立即开始另一次尝试。我当前的查询将包含此结果,但不应包含此结果。

使用示例数据

编辑我希望这已经足够,否则我可以上传一些示例数据):

|"183.3.202.190" | "2016-05-07 09:36:55.294747" |
|"183.3.202.190" | "2016-05-07 10:36:55.294747" |
|"183.3.202.190" | "2016-05-07 11:36:55.294747" |
|"183.3.202.190" | "2016-05-07 12:36:55.294747" |
|"183.3.202.190" | "2016-05-07 13:36:55.294747" |
|"183.3.202.191" | "2016-05-07 09:36:55.294747" |
|"183.3.202.191" | "2016-05-07 10:36:55.294747" |
|"183.3.202.191" | "2016-05-07 11:36:55.294747" |

应该返回:

183.3.202.190" | 5 
183.3.202.191  | 3

因为从第一次尝试开始,它在24小时窗口中的尝试次数少于5次

|"183.3.202.191" | "2016-05-07 09:36:55.294747" |
|"183.3.202.191" | "2016-05-07 10:36:55.294747" |
|"183.3.202.191" | "2016-05-07 11:36:55.294747" |
|"183.3.202.191" | "2016-05-07 12:36:55.294747" |
|"183.3.202.191" | "2016-05-07 13:36:55.294747" |
|"183.3.202.191" | "2016-05-07 13:36:55.294747" |

应返回NULL,因为从第一次尝试开始,它在24小时窗口中的次数超过5次

1 个答案:

答案 0 :(得分:1)

试试这个:

 select attackerip,stamp_init,count(*) attack_count from (
   select a.attackerip,stamp,min(stamp_init) stamp_init,min(stamp_24) stamp_24 from thesislog_v2 a
join (
  select attackerip,stamp stamp_init,stamp+'24 hours'::interval stamp_24 from thesislog_v2
   ) b on (a.attackerip=b.attackerip and a.stamp between b.stamp_init and b.stamp_24) 
  group by 1,2
) c group by 1,2
having count(*) <=5

在您的第一个样本数据上,结果与您的预期相同 在第二次返回5次攻击时,因为你有两行具有相同的attackerip / stamp(是正常吗?),如果你在最后一个时间戳添加一毫秒,查询会找到6行并返回null,就像它预期的那样。 如果您在第一个样本中添加一行,如下所示:

|"183.3.202.190" | "2016-05-07 09:36:55.294747" |
|"183.3.202.190" | "2016-05-07 10:36:55.294747" |
|"183.3.202.190" | "2016-05-07 11:36:55.294747" |
|"183.3.202.190" | "2016-05-07 12:36:55.294747" |
|"183.3.202.190" | "2016-05-07 13:36:55.294747" |
|"183.3.202.191" | "2016-05-07 09:36:55.294747" |
|"183.3.202.191" | "2016-05-07 10:36:55.294747" |
|"183.3.202.191" | "2016-05-07 11:36:55.294747" |
|"183.3.202.191" | "2016-05-08 11:37:55.294747" |

结果是:

 183.3.202.191  2016-05-08 11:37:55.294747  1
 183.3.202.190  2016-05-07 09:36:55.294747  5
 183.3.202.191  2016-05-07 09:36:55.294747  3

这是你想要的吗?