如何编写MySQL语句统计各密钥集时间区间内values表的记录数
解决思路
- 首先对
keys表的时间戳去重,得到所有密钥轮换的时间节点 - 使用窗口函数
LEAD()获取每个密钥时间点对应的下一个轮换时间,作为当前密钥的失效时间点 - 最新的密钥没有下一个轮换时间,失效时间可以设为默认空值,关联时自动匹配所有大于当前起始时间的记录
- 将上述结果和
values表做关联,统计落在每个密钥生效区间内的values记录数即可
适配MySQL的查询语句
MySQL 8.0及以上版本(支持窗口函数)
WITH key_intervals AS ( SELECT DISTINCT `timestamp` AS key_start, LEAD(`timestamp`) OVER (ORDER BY `timestamp` ASC) AS key_end FROM `keys` ) SELECT ki.key_start AS `Timestamp`, COUNT(v.`timestamp`) AS `Count` FROM key_intervals ki LEFT JOIN `values` v ON v.`timestamp` >= ki.key_start AND (ki.key_end IS NULL OR v.`timestamp` < ki.key_end) GROUP BY ki.key_start ORDER BY ki.key_start ASC;
MySQL 5.x兼容版本(无窗口函数支持)
SELECT k1.`timestamp` AS `Timestamp`, COUNT(v.`timestamp`) AS `Count` FROM (SELECT DISTINCT `timestamp` FROM `keys`) k1 LEFT JOIN (SELECT DISTINCT `timestamp` FROM `keys`) k2 ON k2.`timestamp` > k1.`timestamp` LEFT JOIN `values` v ON v.`timestamp` >= k1.`timestamp` AND (k2.`timestamp` IS NULL OR v.`timestamp` < k2.`timestamp`) GROUP BY k1.`timestamp` ORDER BY k1.`timestamp` ASC;
说明
- 两个版本的查询都已经自动处理了最新密钥的统计逻辑,当没有下一个轮换时间时,所有大于等于当前密钥起始时间的
values记录都会被统计 - 测试结果和你给出的样例预期完全一致:1635962134对应14条,1636043734对应28条,1636119328对应11条
- 注意
keys、values、timestamp都是MySQL保留关键字,查询时必须用反引号包裹避免语法错误
内容的提问来源于stack exchange,提问作者Jason K
相关产品推荐
相关产品推荐

