贝利信息

SQL 如何实现“每组取最新一条”?

日期:2026-01-19 00:00 / 作者:舞夢輝影
用ROW_NUMBER()配合子查询或CTE取每组最新记录最常用可靠:按user_id分组、order_time倒序编号,取rn=1;需处理NULL(如加NULLS LAST)和并列(改用RANK);老版本可用关联子查询但性能差;禁用GROUP BY混选非聚合字段。

用窗口函数 ROW_NUMBER() 配合子查询或 CTE 是最常用、最可靠的方法。

用 ROW_NUMBER() 按组排序取 Top 1

核心思路:给每组数据按时间(或 ID)倒序编号,取编号为 1 的记录。

假设表 orders 包含字段 user_idorder_timeamount,要查每个用户最新的一笔订单:

SELECT user_id, order_time, amount
FROM (
  SELECT *,
         ROW_NUMBER() OVER (
           PARTITION BY user_id 
           ORDER BY order_time DESC
         ) AS rn
  FROM orders
) t
WHERE rn = 1;

注意 NULL 和并列情况

如果 order_time 可能为 NULL,需显式处理,否则这些行可能被排在最前或最后(取决于数据库默认行为):

替代方案:关联子查询(兼容老版本)

不支持窗口函数的老数据库(如 MySQL 5.7)可用相关子查询:

SELECT o1.user_id, o1.order_time, o1.amount
FROM orders o1
WHERE o1.order_time = (
  SELECT MAX(o2.order_time)
  FROM orders o2
  WHERE o2.user_id = o1.user_id
);

⚠️ 注意:这个写法在有重复最大时间时会返回多条,且性能通常不如窗口函数,尤其数据量大时。

避免常见错误