T-SQL:用最新的非空值替换 NULL 的最佳方法?

2021-09-10 00:00:00 sql tsql sql-server

假设我有这张表:

+----+-------+
| id | value |
+----+-------+
|  1 |     5 |
|  2 |     4 |
|  3 |     1 |
|  4 |  NULL |
|  5 |  NULL |
|  6 |    14 |
|  7 |  NULL |
|  8 |     0 |
|  9 |     3 |
| 10 |  NULL |
+----+-------+

我想编写一个查询,将任何 NULL 值替换为该列中表中不为空的最后一个值.

I want to write a query that will replace any NULL value with the last value in the table that was not null in that column.

我想要这个结果:

+----+-------+
| id | value |
+----+-------+
|  1 |     5 |
|  2 |     4 |
|  3 |     1 |
|  4 |     1 |
|  5 |     1 |
|  6 |    14 |
|  7 |    14 |
|  8 |     0 |
|  9 |     3 |
| 10 |     3 |
+----+-------+

如果以前的值不存在,则 NULL 是可以的.理想情况下,即使使用 ORDER BY,这也应该能够正常工作.例如,如果我 ORDER BY [id] DESC:

If no previous value existed, then NULL is OK. Ideally, this should be able to work even with an ORDER BY. So for example, if I ORDER BY [id] DESC:

+----+-------+
| id | value |
+----+-------+
| 10 |  NULL |
|  9 |     3 |
|  8 |     0 |
|  7 |     0 |
|  6 |    14 |
|  5 |    14 |
|  4 |    14 |
|  3 |     1 |
|  2 |     4 |
|  1 |     5 |
+----+-------+

如果我ORDER BY [value] DESC:

+----+-------+
| id | value |
+----+-------+
|  6 |    14 |
|  1 |     5 |
|  2 |     4 |
|  9 |     3 |
|  3 |     1 |
|  8 |     0 |
|  4 |     0 |
|  5 |     0 |
|  7 |     0 |
| 10 |     0 |
+----+-------+

我认为这可能涉及某种分析函数 - 以某种方式对值列进行分区 - 但我不确定在哪里查看.

I think this might involve some kind of analytic function - somehow partitioning over the value column - but I'm not sure where to look.

推荐答案

Itzik Ben-Gan 在此处介绍了最佳方法:最后一个非空谜题

The best way has been covered by Itzik Ben-Gan here:The Last non NULL Puzzle

下面是一个在我的系统上处理 1000 万行并在 20 秒内完成的解决方案

Below is a solution which for 10 million rows and completes around in 20 seconds on my system

SELECT
  id,
  value1,
  CAST(
  SUBSTRING(
  MAX(CAST(id AS binary(4)) + CAST(value1 AS binary(4)))
  OVER (ORDER BY id
  ROWS UNBOUNDED PRECEDING),
  5, 4)
  AS int) AS lastval
FROM dbo.T1;

此解决方案假定您的 id 列已编入索引

This solution assumes your id column is indexed

相关文章