Oracle中基于SELECT更新表:将非最新start_date的flag设为N
修正SQL实现按Id更新旧日期记录的Flag字段
原SQL的问题分析
你的原SQL错误在于:子查询仅返回了存在旧日期记录的Id列表,然后对这些Id的所有记录执行更新,导致同一Id下的最新日期记录也被错误地设为'N'。
正确的SQL写法
方法1:关联子查询(通用多数数据库)
UPDATE T1 SET flag = 'N' WHERE flag = 'Y' AND (Id, start_date) NOT IN ( SELECT Id, MAX(start_date) FROM T1 GROUP BY Id );
方法2:JOIN关联(性能更优,适用于MySQL、PostgreSQL等)
UPDATE T1 INNER JOIN ( SELECT Id, MAX(start_date) AS latest_start FROM T1 GROUP BY Id ) AS latest_records ON T1.Id = latest_records.Id SET T1.flag = 'N' WHERE T1.flag = 'Y' AND T1.start_date < latest_records.latest_start;
逻辑说明
两种写法的核心逻辑一致:
- 先按
Id分组,找出每个Id对应的最新start_date - 筛选出原
flag为'Y',且start_date不等于该Id最新日期的记录 - 将这些记录的
flag更新为'N'
执行后即可得到你期望的结果:
T1: Id start_date end_date flag 1 11-Jan-20 11-Jan-20 Y 3 11-Jan-20 11-Jan-20 N 2 11-Jan-20 11-Jan-20 Y 3 11-Mar-21 11-Jan-20 Y
内容的提问来源于stack exchange,提问作者Bahy Mohamed
相关产品推荐
相关产品推荐

