SQL Server中邮编查询结果NULL值用最后非空值填充实现问题
你之前使用LAG()无法得到预期结果,是因为普通LAG()只能取紧邻上一行的数值,如果出现连续多行为NULL的场景,只能替换第一个NULL值,后续NULL还是无法取到更前面的非空IDemp。
方案1:通用SQL实现(兼容所有支持窗口函数的数据库)
思路是先给数据做分组,所有连续的NULL值和它前一个最近的非空值分到同一组,再用组内的非空值填充整组:
WITH base_data AS ( -- 你的原有左联查询结果 SELECT DISTINCT KP.postal, K.IDemp FROM PostalCodes KP LEFT JOIN [Customers] K ON K.postal = KP.postal ), group_mark AS ( SELECT postal, IDemp, -- 每遇到一个非空IDemp,分组标记+1,连续空值会被分到同一个组 SUM(CASE WHEN IDemp IS NOT NULL THEN 1 ELSE 0 END) OVER (ORDER BY postal ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS grp FROM base_data ) SELECT postal, -- 同组内取唯一的非空IDemp填充所有行 MAX(IDemp) OVER (PARTITION BY grp) AS IDemp FROM group_mark ORDER BY postal
方案2:简化写法(仅支持带IGNORE NULLS参数的数据库,如PostgreSQL 11+、Oracle、BigQuery等)
直接用LAST_VALUE函数跳过NULL值取最近的非空值:
SELECT DISTINCT KP.postal, LAST_VALUE(K.IDemp IGNORE NULLS) OVER (ORDER BY KP.postal ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS IDemp FROM PostalCodes KP LEFT JOIN [Customers] K ON K.postal = KP.postal ORDER BY KP.postal
说明
两种方案都保留你示例中开头无前置非空值的行的NULL状态,如果你需要给开头的NULL也分配默认员工,可在最终输出的IDemp字段外加一层COALESCE函数设置默认值即可。
内容的提问来源于stack exchange,提问作者Filip Grzebalski
相关产品推荐
相关产品推荐

