窗口函数默认忽略NULL值进行聚合计算,但NULL参与运算会传播导致结果为NULL;排序中NULL位置影响窗口帧范围;需用COALESCE等处理NULL以避免计算链中断。

窗口函数本身不主动“过滤”或“跳过”NULL,但多数聚合类窗口函数(如 SUM、AVG、MIN、MAX)在计算时默认忽略 NULL 值——这和它们在普通聚合查询中的行为一致。但关键在于:窗口函数的计算结果若依赖含 NULL 的表达式(比如列参与运算),仍会因 NULL 传播而返回 NULL。
聚合类窗口函数自动跳过 NULL
例如 SUM() OVER (PARTITION BY dept ORDER BY date) 只对当前窗口内该列非 NULL 的值求和;AVG(salary) OVER (...) 同样只基于非 NULL 的 salary 计算平均值。如果整个窗口中该列全为 NULL,结果就是 NULL。
-
COUNT(column) OVER (...)统计非 NULL 值个数 -
COUNT(*) OVER (...)统计所有行(含 NULL 行) -
MIN()/MAX() OVER (...)忽略 NULL,返回其余值中的极值
排序与帧边界受 NULL 影响
在 ORDER BY 子句中,NULL 默认排在最前(ASC)或最后(DESC),具体取决于数据库设置。这会影响窗口帧(如 ROWS BETWEEN 2 PRECEDING AND 2 FOLLOWING)的实际范围。若排序列存在大量 NULL,可能导致相邻行逻辑错位,使窗口包含意外数据。
- 建议显式控制 NULL 排序:用
ORDER BY col ASC NULLS LAST(PostgreSQL/Oracle)或等效写法 - MySQL 和 SQL Server 不直接支持
NULLS FIRST/LAST,可用ORDER BY IF(col IS NULL, 1, 0), col模拟
NULL 传播会破坏计算链
这是最容易出错的地方。比如你写:LAG(sales) OVER (...) + LEAD(sales) OVER (...)
只要其中任意一个为 NULL,整条结果就是 NULL——即使另一个有值。
- 必须提前处理:用
COALESCE(LAG(sales), 0)或ISNULL(LEAD(sales), 0) - 对需要加总、拼接、比较的窗口表达式,一律先用
COALESCE或CASE WHEN ... IS NULL THEN ... END转义 - 跨库兼容优先选
COALESCE(expr, 0),比IFNULL或ISNULL更稳妥
ROW_NUMBER / RANK 类函数对 NULL 不敏感
ROW_NUMBER()、RANK()、DENSE_RANK() 仅依赖 ORDER BY 的顺序,不涉及值计算,所以 NULL 本身不会导致报错或中断。但若 ORDER BY 列全是 NULL,这些函数仍会按物理顺序编号(行为因数据库而异,不保证稳定)。
- 为避免不确定性,应在
ORDER BY中加入确定性次级排序,例如:ORDER BY dept_id, id - 不要依赖 NULL 值在排序中的位置做业务逻辑判断










