You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server中无需新增列,如何在窗口内获取首个非空值?

在SQL Server窗口中获取第一个非空值(无需新增列)

由于SQL Server的FIRST_VALUE()不支持IGNORE NULLS参数,你可以通过以下几种方式实现需求:

方法1:适用于所有SQL Server版本

利用CASE语句调整排序权重,让非空值排在窗口最前面,再通过FIRST_VALUE()获取第一个值:

SELECT
    分区列名,
    排序列名,
    目标列名,
    FIRST_VALUE(目标列名) OVER (
        PARTITION BY 分区列名
        ORDER BY 
            CASE WHEN 目标列名 IS NOT NULL THEN 0 ELSE 1 END,  -- 非空值优先排序
            排序列名  -- 保持原排序逻辑
        ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
    ) AS 第一个非空值
FROM 你的表名;

原理:通过CASE给非空值分配更低的排序优先级,确保它们出现在窗口的最前面,FIRST_VALUE()就能取到第一个非空值,且该值会被应用到整个分区的所有行。

方法2:适用于SQL Server 2022及以上版本

SQL Server 2022开始支持NULLS LAST/NULLS FIRST,可以简化写法:

SELECT
    分区列名,
    排序列名,
    目标列名,
    FIRST_VALUE(目标列名) OVER (
        PARTITION BY 分区列名
        ORDER BY 排序列名
        NULLS LAST  -- 将空值排在末尾,确保第一个非空值被选中
    ) AS 第一个非空值
FROM 你的表名;

方法3:基于累计计数的实现

通过累计非空值的数量,标记出第一个非空值的位置,再广播到整个分区:

SELECT
    分区列名,
    排序列名,
    目标列名,
    MAX(CASE WHEN 非空累计数 = 1 THEN 目标列名 END) OVER (PARTITION BY 分区列名) AS 第一个非空值
FROM (
    SELECT
        *,
        SUM(CASE WHEN 目标列名 IS NOT NULL THEN 1 ELSE 0 END) OVER (
            PARTITION BY 分区列名
            ORDER BY 排序列名
            ROWS UNBOUNDED PRECEDING
        ) AS 非空累计数
    FROM 你的表名
) AS 子查询;

原理:非空累计数会从0开始,第一次遇到非空值时变为1,用MAX()将该值覆盖到整个分区的所有行。

注意:以上方法均无需新增持久化列,所有计算都在窗口函数或子查询中完成,符合你的需求。

内容的提问来源于stack exchange,提问作者Zar Ha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 01:42:28