求助:使用窗口函数填充同empid下NULL的due_date字段
问题:填充同empid下NULL的due_date值
原始数据
empid claimid flag due_date ------------------------------------------ 123 777 Y 09/01/2023 123 778 N NULL
需求说明
为empid相同但claimid不同的行中,due_date为NULL的记录填充值,取同empid下flag='Y'的行的due_date值,期望输出如下:
empid claimid flag due_date ------------------------------------------ 123 777 Y 09/01/2023 123 778 N 09/01/2023
测试数据代码
declare @t table ( empid int, claimid int, flag char(1), due_date date ) insert into @t values (123, 777, 'Y', '09/01/2023'), (123, 778, 'N', NULL)
尝试的代码
select *, row_number() over (partition by empid order by due_date desc) as rownum from @t
解决方案
你的思路方向是对的,但不需要用row_number(),更直接的方式是用窗口函数MAX()或者FIRST_VALUE(),结合条件筛选出同empid下flag='Y'的due_date值,来填充NULL。
方法1:使用MAX()窗口函数
利用MAX()配合CASE只筛选flag='Y'的due_date,然后跨同empid的行共享这个值:
select empid, claimid, flag, ISNULL(due_date, MAX(CASE WHEN flag = 'Y' THEN due_date END) OVER (PARTITION BY empid)) as due_date from @t
方法2:使用FIRST_VALUE()窗口函数
指定按flag排序,优先取flag='Y'的行的due_date,同样跨同empid的行生效:
select empid, claimid, flag, ISNULL(due_date, FIRST_VALUE(due_date) OVER (PARTITION BY empid ORDER BY CASE WHEN flag = 'Y' THEN 0 ELSE 1 END)) as due_date from @t
方法3:如果要更新原表数据
如果需要直接更新表中的NULL值,而非仅查询输出,可以用关联更新:
update t1 set due_date = t2.due_date from @t t1 join @t t2 on t1.empid = t2.empid where t1.due_date is null and t2.flag = 'Y'
思路说明
你想用窗口函数的方向是正确的,但row_number()在这里不是最优选择——它主要用来给行编号,而我们需要的是获取同组内特定条件的字段值。上面的方法都是基于窗口函数的分组特性,直接提取目标值来填充NULL,更高效简洁。
内容的提问来源于stack exchange,提问作者jackstraw22
相关产品推荐
相关产品推荐

