Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 用给定分区内以前的非空值替换空值_Sql_Sql Server_Sql Server 2019 - Fatal编程技术网

Sql 用给定分区内以前的非空值替换空值

Sql 用给定分区内以前的非空值替换空值,sql,sql-server,sql-server-2019,Sql,Sql Server,Sql Server 2019,如何计算新列,其中来自Number列的NULL值将替换为以前的非NULL值?NotNULL应保持不变。都在客户的分区内 +----------+------------+--------+ | Customer | Date | Number | +----------+------------+--------+ | A | 2016-01-01 | 9,00 | | A | 2020-01-01 | NULL | | A | 20

如何计算新列,其中来自
Number
列的
NULL
值将替换为以前的非NULL值?Not
NULL
应保持不变。都在
客户的分区内

+----------+------------+--------+
| 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   |
+----------+------------+--------+
假设:

  • 输入数据是按客户、日期排序的
    ,输出数据也是如此
  • 每个
    客户的第一行(最早的一行)
    将始终具有不同于
    NULL

如果SQL Server支持
延迟(忽略空值)
,这将更容易实现。但事实并非如此。您可以通过对具有值的行进行累积计数,然后分散这些值来定义组:

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
执行此操作,但我怀疑在几乎所有情况下,上述操作都会更快。

如果SQL Server支持
延迟(忽略空值)
,这将更容易。但事实并非如此。您可以通过对具有值的行进行累积计数,然后分散这些值来定义组:

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;
    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

您也可以使用
apply
来实现这一点,但我怀疑在几乎所有情况下,上述操作都会更快。

这也可行,但是带有OVER的更容易合并到我的查询中,这里对其进行了简化。这也可行,但是带有OVER的更容易合并到我的查询中,这里对其进行了简化。
    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