贝利信息

SQL 窗口函数如何处理 NULL?

日期:2026-01-19 00:00 / 作者:冰川箭仙
窗口函数默认忽略NULL值进行聚合计算,但NULL参与运算会传播导致结果为NULL;排序中NULL位置影响窗口帧范围;需用COALESCE等处理NULL以避免计算链中断。

窗口函数本身不主动“过滤”或“跳过”NULL,但多数聚合类窗口函数(如 SUMAVGMINMAX)在计算时默认忽略 NULL 值——这和它们在普通聚合查询中的行为一致。但关键在于:窗口函数的计算结果若依赖含 NULL 的表达式(比如列参与运算),仍会因 NULL 传播而返回 NULL。

聚合类窗口函数自动跳过 NULL

例如 SUM() OVER (PARTITION BY dept ORDER BY date) 只对当前窗口内该列非 NULL 的值求和;AVG(salary) OVER (...) 同样只基于非 NULL 的 salary 计算平均值。如果整个窗口中该列全为 NULL,结果就是 NULL。

排序与帧边界受 NULL 影响

ORDER BY 子句中,NULL 默认排在最前(ASC)或最后(DESC),具体取决于数据库设置。这会影响窗口帧(如 ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING)的实际范围。若排序列存在大量 NULL,可能导致相邻行逻辑错位,使窗口包含意外数据。

NULL 传播会破坏计算链

这是最容易出错的地方。比如你写:
LAG(sales) OVER (...) + LEAD(sales) OVER (...)
只要其中任意一个为 NULL,整条结果就是 NULL——即使另一个有值。

ROW_NUMBER / RANK 类函数对 NULL 不敏感

ROW_NUMBER()RANK()DENSE_RANK() 仅依赖 ORDER BY 的顺序,不涉及值计算,所以 NULL 本身不会导致报错或中断。但若 ORDER BY 列全是 NULL,这些函数仍会按物理顺序编号(行为因数据库而异,不保证稳定)。