T-SQL查询更新空值

时间:2012-05-18 14:28:21

标签: sql-server tsql common-table-expression

我在T-SQL中有一个非常具体的问题。

如果我能解决这个案例,我会告诉你,我想我能解决原来的案子。

将这些数据放在表格中:

DECLARE @Test TABLE
(
    Value INT
    ,Date DATETIME2(7)
);

INSERT INTO @Test
VALUES
(NULL, '2011-01-01 10:00'),
(NULL, '2011-01-01 11:00'),
(2, '2011-01-01 12:00'),
(NULL, '2011-01-01 13:00'),
(3, '2011-01-01 14:00'),
(NULL, '2011-01-01 15:00'),
(NULL, '2011-01-01 16:00'),
(4, '2011-01-01 17:00'),
(NULL, '2011-01-01 18:00'),
(5, '2011-01-01 19:00'),
(6, '2011-01-01 20:00')

我需要选择此输出:

Value   Date
2       2011-01-01 10:00
2       2011-01-01 11:00
2       2011-01-01 12:00
2       2011-01-01 13:00
3       2011-01-01 14:00
3       2011-01-01 15:00
3       2011-01-01 16:00
4       2011-01-01 17:00
4       2011-01-01 18:00
5       2011-01-01 19:00
6       2011-01-01 20:00

给出一些解释。如果某个地方的值为NULL,我需要使用前一小时的值进行更新。如果一行中有多个空值,则具有非空值的最接近的早期小时将传播并填充所有这些空值。此外,如果当天的第一个小时为空,那么具有非空值的当天最早的小时在这种情况下向下传播,如2。在您的情况下,您可以假设至少有一个值是非空值。

我的目标是使用Common表表达式或类似的东西来解决这个问题。用光标的方式我认为如果我尝试的话,我会在很短的时间内得到解决方案,但到目前为止我对CTE和递归CTE的尝试都失败了。

2 个答案:

答案 0 :(得分:3)

由于你的病情并不总是一样,这有点困难。在您的示例中,前两行需要从第一个值获取其值以及更晚的日期,在其他情况下,它们需要从先前日期获取值。如果您总是需要查看以前的日期,则可以简单地执行此查询:

SELECT  B.Value,
        A.[Date]
FROM @Test A
OUTER APPLY (SELECT TOP 1 *
             FROM @Test
             WHERE [Date] <= A.[Date] AND Value IS NOT NULL
             ORDER BY [Date] DESC) B

但在你的情况下,我认为你需要这个:

SELECT  ISNULL(B.Value,C.Value) Value,
        A.[Date]
FROM @Test A
OUTER APPLY (SELECT TOP 1 *
             FROM @Test
             WHERE [Date] <= A.[Date] AND Value IS NOT NULL
             ORDER BY [Date] DESC) B
OUTER APPLY (SELECT TOP 1 *
             FROM @Test
             WHERE Value IS NOT NULL
             ORDER BY [Date]) C

答案 1 :(得分:2)

试试这个:

select 
    t.value, t.date
      ,COALESCE(t.value
               ,(select MAX(tt.value) from @Test tt WHERE t.Date>tt.Date)
               ,(SELECT MIN(ttt.Value) FROM @Test ttt Where ttt.Date IS NOT NULL)
               ) AS UseValue
    from @Test   t

输出:

value       date                    UseValue
----------- ----------------------- -----------
NULL        2011-01-01 10:00:00.000 2
NULL        2011-01-01 11:00:00.000 2
2           2011-01-01 12:00:00.000 2
NULL        2011-01-01 13:00:00.000 2
3           2011-01-01 14:00:00.000 3
NULL        2011-01-01 15:00:00.000 3
NULL        2011-01-01 16:00:00.000 3
4           2011-01-01 17:00:00.000 4
NULL        2011-01-01 18:00:00.000 4
5           2011-01-01 19:00:00.000 5
6           2011-01-01 20:00:00.000 6