将空值替换为行SQL SQL Server查询中的先前可用值

时间:2016-01-28 00:13:11

标签: sql-server-2008

我正在寻找构建一个查询,用以前的可用值替换null值。有人帮忙。这是当前看起来像的表

11/30/2015   ID1     CLassName   1
NULL         ID1     CLassName   2
NULL         ID1     CLassName   3
NULL         ID1     CLassName   4
11/30/2015   ID1     CLassName   5
NULL         ID1     CLassName   6
NULL         ID1     CLassName   7
12/31/2015   ID1     CLassName   1
NULL         ID1     CLassName   2
NULL         ID1     CLassName   3
NULL         ID1     CLassName   4
12/31/2015   ID1     CLassName   5
NULL         ID1     CLassName   6
NULL         ID1     CLassName   7

输出应为

11/30/2015       ID1     CLassName   1
11/30/2015       ID1     CLassName   2
11/30/2015       ID1     CLassName   3
11/30/2015       ID1     CLassName   4
11/30/2015       ID1     CLassName   5
11/30/2015       ID1     CLassName   6
11/30/2015       ID1     CLassName   7
12/31/2015       ID1     CLassName   1
12/31/2015       ID1     CLassName   2
12/31/2015       ID1     CLassName   3
12/31/2015       ID1     CLassName   4
12/31/2015       ID1     CLassName   5
12/31/2015       ID1     CLassName   6
12/31/2015       ID1     CLassName   7

6 个答案:

答案 0 :(得分:3)

以下声明完美运作

SELECT 
CASE WHEN DATE1 IS NULL 
     THEN 
(SELECT TOP 1 DATE1 FROM Table1 WHERE ID2<T.ID2 
  AND Date1 IS NOT NULL ORDER BY ID2 DESC) ELSE Date1 END AS DATENEW,
*FROM Table1 T

输出如下

        DATENEW             Date1          ID   Class      ID2
        11/30/2015          11/30/2015     ID1  ClassName   1
        11/30/2015          NULL           ID1  ClassName   2
        11/30/2015          NULL           ID1  ClassName   3
        11/30/2015          NULL           ID1  ClassName   4
        12/31/2015          12/31/2015     ID1  ClassName   5
        12/31/2015          NULL           ID1  ClassName   6
        12/31/2015          NULL           ID1  ClassName   7

答案 1 :(得分:0)

可能类似于下面给出的代码。

注意:代码未经过测试。此外,此代码需要考虑是否需要基于ID列的先前值或任何其他类似的要求。

CREATE TABLE Table1 (Date1 VARCHAR(10), ID VARCHAR(10), Class VARCHAR(10), ID2 INT);

INSERT INTO Table1 Values ('11/30/2015', 'ID1', 'ClassName', 1);
INSERT INTO Table1 Values (NULL, 'ID1', 'ClassName', 2);
INSERT INTO Table1 Values (NULL, 'ID1', 'ClassName', 3);
INSERT INTO Table1 Values (NULL, 'ID1', 'ClassName', 4);
INSERT INTO Table1 Values ('12/31/2015', 'ID1', 'ClassName', 5);
INSERT INTO Table1 Values (NULL, 'ID1', 'ClassName', 6);
INSERT INTO Table1 Values (NULL, 'ID1', 'ClassName', 7);

CREATE TABLE Table2 (Date1 VARCHAR(10), ID VARCHAR(10), Class VARCHAR(10), ID2 INT);

DECLARE @Date1 VARCAHR(10), @ID1 VARCHAR(10), @Class VARCHAR(10), @ID2 INT;
DECLARE @TempDate1 VARCAHR(10); --set default if first record is null

DECLARE CURSOR MYCUR FOR
SELECT Date1, ID1, Class, ID2
FROM Table1;
OPEN MYCUR
FETCH NEXT FROM MYCUR INTO @Date1, @ID1, @Class, @ID2

WHILE @@FETCH_STATUS = 0
BEGIN

    IF (@Date1 IS NOT NULL)
    BEGIN
        @TempDate1=@Date1
    END

    INSERT INTO Table2 VALUES(@TempDate1, @ID1, @Class, @ID2)

    FETCH NEXT FROM MYCUR INTO @Date1, @ID1, @Class, @ID2
END

CLOSE MYCUR
DEALLOCATE MYCUR

SELECT * FROM Table2

答案 2 :(得分:0)

我认为这应该有效,我假设表名和列名,因为你没有提供这些,也假设id是你订购行的列

 UPDATE table1 T
    SET T.date1 = (
                     SELECT MAX(T2.date)
                       FROM table1 T2
                      WHERE T2.date IS NOT NULL
                        AND T2.id <= T.id
                  )
  WHERE T.date1 IS NULL

答案 3 :(得分:0)

这个问题有点老了,但是您可以将first_row function与SQL Server一起使用(从2012版开始)

首先,您可以创建一个新列,其中包含非空日期的每个“块”以及所有接下来的空值的递增数字:

WITH CTE AS
(
    SELECT *,
           SUM(CASE WHEN Date1 is NULL then 0 else 1 END) AS block
    FROM your_table
)

此CTE将创建类似这样的内容(我使用的是Shakeer的答案的列名称):

Date1          ID   Class      ID2    block
11/30/2015     ID1  ClassName   1      1
NULL           ID1  ClassName   2      1
NULL           ID1  ClassName   3      1
NULL           ID1  ClassName   4      1
12/31/2015     ID1  ClassName   5      2
NULL           ID1  ClassName   6      2
NULL           ID1  ClassName   7      2

现在,您可以使用first_row函数来获取每个“块”的第一个值:

SELECT *,
        first_row(Date1) OVER (PARTITION BY block ORDER BY ID2) AS NewDate
FROM CTE

我希望这会有所帮助。

答案 4 :(得分:0)

使用 MS Access 对我有用的方法是添加一个自动编号 (ID) 字段以建立固定顺序,然后使用带有源表副本和合适 where 条件的更新语句:

UPDATE Table, Table AS Table_1 SET Table.Field  = [Table_1].[Field]
WHERE (((Table_1.Field) Is Not Null) AND ((Table_1.ID)<[Table].[ID]));

答案 5 :(得分:-1)

您可以使用Update语句。

用于生成数据的示例查询:

CREATE TABLE table1 (Date1 date)

insert into Table1 values ('11/30/2015')
insert into Table1 values (NULL)
insert into Table1 values (NULL)
insert into Table1 values ('11/20/2016')
insert into Table1 values (NULL)
insert into Table1 values ('10/12/2017')
insert into Table1 values (NULL)

还有带有更新语句的查询

DECLARE @n date
UPDATE Table1 
SET 
    @n = COALESCE(DATE1, @n),
    DATE1 = COALESCE(DATE1, @n)

 SELECT * from table1

输出:

Date1
2015-11-30
2015-11-30
2015-11-30
2016-11-20
2016-11-20
2017-10-12
2017-10-12