SQL 使用窗口函数实现“去重保留最新”

9次阅读

窗口函数“去重保留最新”的核心是按业务主键分组并依时间或ID倒序排序,用ROW_NUMBER()标序后取rn=1;DISTINCT和GROUP BY无法可控留指定记录,而窗口函数可灵活扩展为保留最新N条。

SQL 使用窗口函数实现“去重保留最新”

用窗口函数实现“去重保留最新”,核心是先按分组和时间(或序号)排序,再给每组内的记录标序号,最后取每组序号为 1 的那条。

按业务主键分组 + 时间字段倒序

假设有一张用户操作日志表 user_log,含字段:user_idactioncreated_at(时间戳),需对每个 user_id 只保留最新一条记录。

写法如下:

select user_id, action, created_at FROM (   SELECT *,          ROW_NUMBER() OVER (            PARTITION BY user_id             ORDER BY created_at DESC          ) AS rn   FROM user_log ) t WHERE rn = 1;

用 ID 替代时间字段(当无明确时间字段时)

如果表里没有时间字段,但有自增主键 id,且插入顺序与“新旧”逻辑一致,可直接按 id DESC 排序:

  • PARTITION BY user_id 分组
  • ORDER BY id DESC 让最大 ID 排第一
  • ROW_NUMBER() 标出组内顺序,取 rn = 1

注意 DISTINCT 和 GROUP BY 不适用的场景

DISTINCT 只能去完全重复行,无法控制“留哪一条”;GROUP BY 若选非分组字段(如 action)会报错或结果不可控。窗口函数才是可控去重的标准解法。

扩展:保留最新 N 条(比如每人最近 3 次操作)

只需把 WHERE rn = 1 改成 WHERE rn 即可,灵活度高。

text=ZqhQzanResources