如何从重复ID的行中筛选最大日期记录?SQL优化求助
解决重复ID_PROC_VERSION保留最大FH_ENVIO记录的问题
方案一:使用窗口函数ROW_NUMBER()(推荐)
这种方式能精准控制每个ID_PROC_VERSION分组下仅保留最新(FH_ENVIO最大)的一条记录,逻辑清晰且兼容性强:
WITH ranked_envios AS ( SELECT ER.ID_PROC_VERSION, P.ID || ' / ' || PV.COD_PROCEDIMIENTO || ' / ' || P.COD_SIA AS COD_GC_IPSC_SIA, PV.DENOMINACION, ER.TIPO_ENVIO, ER.RESULTADO_ENVIO, ER.FH_ENVIO, -- 按ID_PROC_VERSION分组,FH_ENVIO降序排序,每组第一条标记为1 ROW_NUMBER() OVER (PARTITION BY ER.ID_PROC_VERSION ORDER BY ER.FH_ENVIO DESC) AS rn FROM ENVIO_REC ER INNER JOIN PROCEDIMIENTO_VERSION PV ON ER.ID_PROC_VERSION = PV.ID INNER JOIN PROCEDIMIENTO P ON PV.ID_PROCEDIMIENTO = P.ID ) SELECT ID_PROC_VERSION, COD_GC_IPSC_SIA, DENOMINACION, TIPO_ENVIO, RESULTADO_ENVIO, FH_ENVIO FROM ranked_envios WHERE rn = 1;
如果需要保留所有FH_ENVIO等于最大值的行(而非仅一条),可以把ROW_NUMBER()换成RANK()或DENSE_RANK()。
方案二:改进原关联查询逻辑
如果不想用CTE,也可以用关联子查询直接匹配每个ID_PROC_VERSION的最大日期:
SELECT ER.ID_PROC_VERSION, P.ID || ' / ' || PV.COD_PROCEDIMIENTO || ' / ' || P.COD_SIA AS COD_GC_IPSC_SIA, PV.DENOMINACION, ER.TIPO_ENVIO, ER.RESULTADO_ENVIO, ER.FH_ENVIO FROM ENVIO_REC ER INNER JOIN PROCEDIMIENTO_VERSION PV ON ER.ID_PROC_VERSION = PV.ID INNER JOIN PROCEDIMIENTO P ON PV.ID_PROCEDIMIENTO = P.ID WHERE ER.FH_ENVIO = ( SELECT MAX(FH_ENVIO) FROM ENVIO_REC ER2 WHERE ER2.ID_PROC_VERSION = ER.ID_PROC_VERSION );
原SQL问题分析
你的原语句出现“重复ID行被全部移除”的情况,大概率是以下原因:
- 时间精度不匹配:如果
FH_ENVIO是带毫秒/微秒的时间类型,子查询的MAX(FH_ENVIO)可能因为隐式转换或显示截断,和原表中的实际值不匹配,导致IN子句无法命中任何行。 - 分组逻辑遗漏:单独运行子查询
SELECT ID_PROC_VERSION, MAX(FH_ENVIO) FROM ENVIO_REC GROUP BY ID_PROC_VERSION,检查是否包含你需要保留的ID_PROC_VERSION,以及对应的日期值是否和原表一致。
内容的提问来源于stack exchange,提问作者Antonio
相关产品推荐
相关产品推荐

