You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL问题:如何按Id分组获取对应最大Date的完整记录?

嘿,这个问题我熟!我来给你拆解一下解决方案👇

问题分析与解决方案

1. 能不能直接在GROUP BY子句中带出对应最大Date的Name?

首先明确:不行。标准SQL的GROUP BY规则要求,SELECT里的非聚合字段必须要么出现在GROUP BY中,要么被聚合函数包裹。如果强行把Name加入GROUP BY,会按Id+Name分组,结果就不是每个Id只返回一条记录了——这显然不符合你的需求。

虽然有些数据库有非标准扩展(比如关闭MySQL的ONLY_FULL_GROUP_BY),但这种写法不通用,还可能返回不确定的结果,完全不推荐。

2. 三种实用解决方案

方法一:子查询+双字段内连接

你之前尝试连接但不会用双字段?其实很简单,连接条件同时匹配Id和Date(子查询得到的每个Id的最大日期),就能精准定位到对应行:

-- 替换your_table为你的实际表名
SELECT t.Id, t.Date, t.Name
FROM your_table t
INNER JOIN (
    -- 先拿到每个Id的最大日期
    SELECT Id, MAX(Date) AS max_date
    FROM your_table
    GROUP BY Id
) sub_query 
    ON t.Id = sub_query.Id 
    AND t.Date = sub_query.max_date;

这个方法兼容性拉满,几乎所有数据库都支持。

方法二:窗口函数(推荐)

如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server、Oracle等),用ROW_NUMBER()会更简洁直观:

WITH ranked_records AS (
    SELECT 
        Id, Date, Name,
        -- 按Id分组,日期倒序排名,最大日期的行排名为1
        ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Date DESC) AS row_rank
    FROM your_table
)
SELECT Id, Date, Name
FROM ranked_records
WHERE row_rank = 1;
  • 如果存在同一个Id有多个相同最大日期的情况,ROW_NUMBER()会随机选一条;如果想保留所有符合条件的行,把ROW_NUMBER()换成RANK()或DENSE_RANK()即可。
  • 这种写法逻辑清晰,后期维护起来特别方便。

方法三:自连接筛选(适合旧版本MySQL)

如果是没有窗口函数的旧版本MySQL,可以用左自连接的方式筛选出最大日期的行:

SELECT t1.Id, t1.Date, t1.Name
FROM your_table t1
LEFT JOIN your_table t2 
    ON t1.Id = t2.Id 
    AND t1.Date < t2.Date -- 找同一个Id下日期更大的记录
WHERE t2.Id IS NULL; -- 找不到更大的日期,说明t1就是最新记录

总结

优先推荐窗口函数的写法,逻辑清晰易维护;如果需要兼容旧数据库,选择子查询连接或自连接的方法。

内容的提问来源于stack exchange,提问作者mikizas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:23:10