我正在寻找构建一个查询来用以前的可用值替换空值。有人可以帮忙。这是当前看起来像的表
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)
下面的语句完美地工作
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)
这个问题有点老了,但是你可以使用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)
我希望这有帮助。
也许类似于下面给出的代码。
注意:代码未经测试。此外,此代码还需要考虑您是否需要基于 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)
| 归档时间: |
|
| 查看次数: |
15739 次 |
| 最近记录: |