我的表格如下:
| 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次
答案 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
这是你想要的吗?