如何按SPECNUMBER分组筛选每组最新CHANGEDATE对应的数据行?
按分组筛选最新日期的所有行
嘿,我懂你遇到的问题了!你想要按SPECNUMBER分组,只保留每个组里最新CHANGEDATE对应的所有行,但直接用MAX(CHANGEDATE)只会返回整个数据集里的最大日期记录,没法按组筛选。别担心,这里有两种靠谱的解决方案,适配大多数SQL数据库:
方法1:子查询+关联(通用SQL写法)
先通过子查询获取每个SPECNUMBER对应的最新日期,再把原表和这个结果关联,筛选出匹配的行:
SELECT t.SPECNUMBER, t.CHANGEDATE, t.CHANGE FROM your_table t INNER JOIN ( -- 先分组得到每个SPECNUMBER的最新日期 SELECT SPECNUMBER, MAX(CHANGEDATE) AS latest_date FROM your_table GROUP BY SPECNUMBER ) sub ON t.SPECNUMBER = sub.SPECNUMBER AND t.CHANGEDATE = sub.latest_date ORDER BY t.SPECNUMBER, t.CHANGE;
注意日期格式的坑
如果你的CHANGEDATE是字符串类型(比如示例里的01/01/2019),直接用MAX()可能会因为字符串排序逻辑出错(比如30/07/2019作为字符串会比01/01/2020大,但实际日期是2020年更新)。这时候需要先把字符串转成日期类型:
- MySQL:用
STR_TO_DATE(CHANGEDATE, '%d/%m/%Y')(适配示例的日/月/年格式) - SQL Server:用
CONVERT(DATE, CHANGEDATE, 103) - PostgreSQL:用
TO_DATE(CHANGEDATE, 'DD/MM/YYYY')
修改后的子查询示例(MySQL):
SELECT SPECNUMBER, MAX(STR_TO_DATE(CHANGEDATE, '%d/%m/%Y')) AS latest_date FROM your_table GROUP BY SPECNUMBER
关联时也要同步转换原表的日期字段哦。
方法2:窗口函数(更简洁的现代SQL写法)
用窗口函数RANK()给每个分组内的行按日期排序,然后筛选出排名第一的行:
SELECT SPECNUMBER, CHANGEDATE, CHANGE FROM ( SELECT SPECNUMBER, CHANGEDATE, CHANGE, -- 按SPECNUMBER分组,日期倒序排名,最新日期的行排名为1 RANK() OVER (PARTITION BY SPECNUMBER ORDER BY CHANGEDATE DESC) AS date_rank FROM your_table ) ranked WHERE date_rank = 1 ORDER BY SPECNUMBER, CHANGE;
为什么用RANK()?
如果同一个SPECNUMBER下有多个相同的最新日期(比如某天多次更新),RANK()会给这些行都标记为1,能完整保留所有最新日期的记录,完全匹配你的需求。
记得把代码里的your_table替换成你实际使用的表名哦!
内容的提问来源于stack exchange,提问作者L M
相关产品推荐
相关产品推荐

