SQL按ID分组替换首尾记录日期为1900-01-01与2999-01-01方案咨询
问题场景
现有存储人员信息的数据表,示例数据如下:
| Id | Start_date | End_date |
|---|---|---|
| 1 | 2007-01-01 | 2007-12-31 |
| 1 | 2008-01-01 | 2009-12-31 |
| 1 | 2010-01-01 | 2011-07-31 |
需求是对同一ID分组的数据,将首条记录的开始日期替换为1900-01-01,末条记录的结束日期替换为2999-01-01。
目前已实现首条日期的替换逻辑,代码如下,希望找到更优的实现方案:
CASE WHEN Start_date = MIN(Start_date) OVER (PARTITION BY id) THEN '1900-01-01' END AS newdate
实现方案参考
你当前的写法逻辑是成立的,但存在边界缺陷:如果同一个ID分组下存在两条Start_date完全相同的记录,会被同时判定为首条,出现匹配错误。更推荐用ROW_NUMBER()直接标记分组内的首尾行,逻辑可控,不会受重复数据影响,性能和原有写法几乎没有差异:
SELECT Id, CASE WHEN rn_asc = 1 THEN '1900-01-01' ELSE Start_date END AS Start_date, CASE WHEN rn_desc = 1 THEN '2999-01-01' ELSE End_date END AS End_date FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Start_date, End_date) AS rn_asc, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Start_date DESC, End_date DESC) AS rn_desc FROM person_info_table ) t
- 写法里给排序增加了End_date作为第二排序键,避免日期重复时排序结果不稳定
- 如果你能100%确定同ID下的Start_date全局唯一,也可以直接在原有写法上补充末条判断逻辑,不需要大改:
CASE WHEN Start_date = MIN(Start_date) OVER (PARTITION BY Id) THEN '1900-01-01' WHEN End_date = MAX(End_date) OVER (PARTITION BY Id) THEN '2999-01-01' ELSE Start_date END AS newdate
注意:如果日期字段是字符串类型,写入固定日期值时要保证格式和原有字段格式一致,避免隐式转换导致的查询错误。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

