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值?NotNULL
应保持不变。都在客户的分区内
+----------+------------+--------+
| 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
延迟(忽略空值)
,这将更容易实现。但事实并非如此。您可以通过对具有值的行进行累积计数,然后分散这些值来定义组:
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