rko*_*egi 8 mysql group-by count
假设我有以下表格:
CREATE TABLE `occurences` (
`object_id` int(10) NOT NULL,
`seen_timestamp` int(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
Run Code Online (Sandbox Code Playgroud)
其中包含对象的ID(不唯一,重复)和观察此对象ID时的时间戳.
观察每周7天,每天24小时运行,并插入每个出现的对象ID和当前时间戳.
现在我想编写查询来选择在任何10分钟时间内至少看过7次的所有对象ID.
它应该像检测入侵一样起作用.
在denyhost脚本中使用类似的算法来检查无效的SSH登录.如果在配置的时间段内找到配置的出现次数,则会阻止IP.
有什么好建议吗?
小智 4
SET @num_occurences = 7; -- how many occurences should occur in the interval
SET @max_period = 10; -- your interval in seconds
SELECT offset_start.object_id FROM
(SELECT @rownum_start := @rownum_start+1 AS idx, object_id, seen_timestamp
FROM occurences, (SELECT @rownum_start:=0) r ORDER BY object_id ASC, seen_timestamp ASC) offset_start
JOIN
(SELECT @rownum_end := @rownum_end + 1 AS idx, object_id, seen_timestamp
FROM occurences, (SELECT @rownum_end:=0) r ORDER BY object_id ASC, seen_timestamp ASC) offset_end
ON offset_start.object_id = offset_end.object_id
AND offset_start.idx + @num_occurences - 1 = offset_end.idx
AND offset_end.seen_timestamp - offset_start.seen_timestamp <= @max_period
GROUP BY offset_start.object_id;
Run Code Online (Sandbox Code Playgroud)
您可以将@num_occurences和移至@num_occurences代码并将它们设置为语句的参数。@rownum_start根据您的客户,您还可以将和的初始化移到@rownum_end查询前面,这可能会提高查询性能(尽管如此,您应该测试一下,只是直觉地查看两个版本的解释)
它选择整个表两次,并将 的每一行与偏移量为 的offset_start行连接起来。(这是通过使用变量创建每行的索引来完成的,模拟其他 RDBMS 中已知的 row_number() 功能)。
然后它只检查两行是否引用相同的object_id并满足周期要求。
由于这是针对每个出现行执行的,因此如果出现次数实际上大于 ,则 object_id 将被返回多次,因此最后会对其进行分组以使返回的s 唯一offset_end@num_occurences@rownum_*@max_occurencesobject_id
| 归档时间: |
|
| 查看次数: |
1075 次 |
| 最近记录: |