消除重复时间:差值小于15分钟的两个timestamp保留最小值的查询方法
时间戳去重实现方案
以下方案均默认表名为event_table,时间戳字段为event_ts,可根据你的实际表结构替换字段名和表名。
场景1:仅相邻两条记录时间差小于15分钟时删除后一条
适合仅需过滤连续上报的冗余数据的场景,实现逻辑简单,性能更高:
-- 通用查询方案,支持MySQL 8.0+/PostgreSQL/SQL Server等支持窗口函数的数据库 WITH ranked_events AS ( SELECT *, -- 以下时间差计算按需三选一即可 -- MySQL版本 TIMESTAMPDIFF(MINUTE, LAG(event_ts, 1, '1970-01-01') OVER (ORDER BY event_ts ASC), event_ts) AS diff_from_prev -- PostgreSQL版本 -- EXTRACT(EPOCH FROM (event_ts - LAG(event_ts, 1, '1970-01-01'::TIMESTAMP) OVER (ORDER BY event_ts ASC))) / 60 AS diff_from_prev -- SQL Server版本 -- DATEDIFF(MINUTE, LAG(event_ts, 1, '1970-01-01') OVER (ORDER BY event_ts ASC), event_ts) AS diff_from_prev FROM event_table ) SELECT * FROM ranked_events WHERE diff_from_prev >= 15;
场景2:最终保留的所有记录时间差均不小于15分钟
适合要求任意两条最终保留的记录间隔都≥15分钟的场景,需用递归CTE实现:
-- MySQL 8.0+ 版本示例 WITH RECURSIVE sorted_events AS ( -- 第一步:给所有记录按时间升序加行号 SELECT *, ROW_NUMBER() OVER (ORDER BY event_ts ASC) AS rn FROM event_table ), filtered_events AS ( -- 递归起点:保留第一条记录 SELECT rn, event_ts FROM sorted_events WHERE rn = 1 UNION ALL -- 递归逻辑:后续记录只有和上一条保留的记录差≥15分钟才保留 SELECT s.rn, s.event_ts FROM sorted_events s JOIN filtered_events f ON s.rn = f.rn + 1 WHERE TIMESTAMPDIFF(MINUTE, f.event_ts, s.event_ts) >= 15 ) -- 关联回原表得到完整的保留数据 SELECT e.* FROM event_table e JOIN filtered_events f ON e.event_ts = f.event_ts;
补充说明
- 如果需要按业务维度分组去重(比如同一个用户/设备的记录才需要做时间去重),只需在窗口函数中增加
PARTITION BY 分组字段即可,示例:LAG(event_ts) OVER (PARTITION BY user_id ORDER BY event_ts ASC) - 物理删除冗余数据前,建议先执行SELECT语句确认待删除数据符合预期,避免误操作
- 15分钟的阈值可根据实际需求调整WHERE条件中的数值即可
内容的提问来源于stack exchange,提问作者shruti
相关产品推荐
相关产品推荐

