将空值替换为 Row SQL 服务器查询中的先前可用值

use*_*726 5 sql-server-2008

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

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
Run Code Online (Sandbox Code Playgroud)

输出看起来像

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
Run Code Online (Sandbox Code Playgroud)

Sha*_*rza 6

下面的语句完美地工作

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
Run Code Online (Sandbox Code Playgroud)

输出如下

        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
Run Code Online (Sandbox Code Playgroud)


Jai*_*rel 5

这个问题有点老了,但是你可以使用SQL Server 的first_value 函数来实现同样的事情(从 2012 版本开始)

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

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

这个 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
Run Code Online (Sandbox Code Playgroud)

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

SELECT *,
        first_value(Date1) OVER (PARTITION BY block ORDER BY ID2) AS NewDate
FROM CTE
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助。


Pra*_*lgi 2

也许类似于下面给出的代码。

注意:代码未经测试。此外,此代码还需要考虑您是否需要基于 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 VARCHAR(10), @ID1 VARCHAR(10), @Class VARCHAR(10), @ID2 INT;
DECLARE @TempDate1 VARCHAR(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
Run Code Online (Sandbox Code Playgroud)