用给定分区内的前一个非空值替换 NULL 值

Replace NULL value with previous not null one within given partition

如何计算新列,其中 Number 列的 NULL 值将替换为先前的非空值?不是 NULL 的应该保持不变。全部在 Customer.

的分区内
+----------+------------+--------+
| Customer |    Date    | Number |
+----------+------------+--------+
| A        | 2016-01-01 | 9,00   |
| A        | 2020-01-01 | NULL   |
| A        | 2020-01-15 | 10,00  |
| A        | 2020-02-01 | NULL   |
| A        | 2020-03-01 | NULL   |
| A        | 2020-03-15 | 11,00  |
| A        | 2020-04-01 | NULL   |
| B        | 2016-01-01 | 9,00   |
| B        | 2020-01-01 | NULL   |
| B        | 2020-01-15 | 10,00  |
| B        | 2020-02-01 | NULL   |
| B        | 2020-03-01 | NULL   |
| B        | 2020-03-15 | 11,00  |
| B        | 2020-04-01 | NULL   |
+----------+------------+--------+

假设:

如果 SQL 服务器支持 lag(ignore nulls),这会更容易。但事实并非如此。您可以通过对具有值的行进行累积计数然后散布这些值来定义组:

select t.*,
       max(number) over (partition by customer, grp)
from (select t.*, count(number) over (partition by customer order by date) as grp
      from t
     ) t;

您也可以使用 apply 执行此操作,但我怀疑上面的方法几乎在所有情况下都更快。

    SELECT customer ,[date] ,case when number is null then B.number else t.number end number
    FROM yourTable t
    CROSS APPLY (
        SELECT TOP 1 number
        FROM yourTable
        WHERE customer = t.customer
            AND number IS NOT NULL
        ORDER BY DATE DESC
        ) B