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

Oracle中按ID分组获取最新日期行的SQL问题求助

如何获取每个ID对应的最新数据行?

先来看下你的测试数据:

测试表(test)数据

idfromtovalue
101.01.2019.01.20100
120.01.2031.12.99100
201.01.2019.01.201001
225.01.2031.12.991001
301.01.2019.01.201002
329.01.2031.12.991002

你的需求是拿到每个id对应的最新行(也就是每个id里from日期最大的那条记录),预期输出也很明确。

为什么你的SQL只返回一行?

你写的这条SQL:

select * from test where id in a AND from = (select max(from) from test where id in a);

有两个关键问题:

  • 变量a根本没定义,而且就算假设a是所有id的集合,你的子查询select max(from) from test where id in a会返回整个表中最大的from日期(也就是29.01.20),然后只筛选from等于这个日期的行,自然只会拿到id=3的那条数据。
  • from是SQL的关键字,直接作为列名用很容易引发语法错误,最好用反引号(`)把它包起来。

正确的解决方案

这里给你三种常用的实现方式,适配不同的数据库环境:

方法1:窗口函数(推荐,支持MySQL8.0+、PostgreSQL、SQL Server等)

用ROW_NUMBER()窗口函数按id分组,然后对每组内的from日期降序排序,取排序后第一行就是最新记录:

SELECT id, `from`, `to`, value
FROM (
    SELECT 
        *,
        ROW_NUMBER() OVER(PARTITION BY id ORDER BY STR_TO_DATE(`from`, '%d.%m.%y') DESC) AS rn
    FROM test
) t
WHERE rn = 1;

注:如果你的from列已经是日期类型,不需要STR_TO_DATE()转换,直接写ORDER BY from DESC就行。

方法2:关联子查询(适合不支持窗口函数的老版本数据库)

为每个id单独计算对应的最大from日期,再匹配原表数据:

SELECT t1.*
FROM test t1
WHERE STR_TO_DATE(t1.`from`, '%d.%m.%y') = (
    SELECT MAX(STR_TO_DATE(t2.`from`, '%d.%m.%y'))
    FROM test t2
    WHERE t2.id = t1.id
);

这个方法会逐行检查每个id的最大日期,确保每个id都能拿到对应的最新行。

方法3:GROUP BY + JOIN

先按id分组拿到每个id的最大from日期,再和原表关联获取完整行:

SELECT t1.*
FROM test t1
JOIN (
    SELECT id, MAX(STR_TO_DATE(`from`, '%d.%m.%y')) AS max_from
    FROM test
    GROUP BY id
) t2 ON t1.id = t2.id AND STR_TO_DATE(t1.`from`, '%d.%m.%y') = t2.max_from;

额外提醒

  • 你的日期格式是dd.mm.yy,要注意年份解析的问题(比如99会被识别为1999还是2099?不同数据库规则不同,得根据业务调整)。
  • 尽量别用SQL关键字当列名,要是必须用,记得用反引号(MySQL)或者方括号(SQL Server)包裹。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 17:27:52