从所有列获取Last NOT NULL值

M.A*_*Ali 2 sql-server sql-server-2008 sql-server-2008-r2

我有一种情况,我试图从所有列中获取最后一个not null值.这里有一些数据用于演示目的.

测试数据

DECLARE @t TABLE (ID INT, Col1 INT, Col2 INT, Col3 INT, Dated DATETIME)
INSERT INTO @t VALUES
(1, NULL, 100  , NULL, '20131210'),  --<-- Column2 from this row
(1, 20  , 200  , NULL, '20131209'),  --<-- Column1 from this row
(1, 30  , NULL , 300 , '20131208'),  --<-- Column3 from this row
(1, 40  , 400  , NULL, '20131207')

?????????????????????????????????????????????????????
? ID ? Col1 ? Col2 ? Col3 ?          Dated          ?
?????????????????????????????????????????????????????
?  1 ? NULL ? 100  ? NULL ? 2013-12-10 00:00:00.000 ?
?  1 ? 20   ? 200  ? NULL ? 2013-12-09 00:00:00.000 ?
?  1 ? 30   ? NULL ? 300  ? 2013-12-08 00:00:00.000 ?
?  1 ? 40   ? 400  ? NULL ? 2013-12-07 00:00:00.000 ?
?????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

我已经构建了一个返回所需结果的查询.但是想知道是否有更高效的方法来做到这一点.从这个方面来说,每当我希望找到一种更有效的方法来获得这些结果时,我就会查询整个表格.

我的查询

SELECT ColumnName, Col1 AS Value, Dated 
 FROM
(
SELECT TOP 1 'Column1' AS ColumnName
            , Col1 
            , Dated
FROM @t
WHERE Col1 IS NOT NULL 
ORDER BY Dated DESC
)Q1

UNION ALL

SELECT * FROM
(
SELECT TOP 1 'Column2' AS ColumnName
            , Col2 
            , Dated
FROM @t
WHERE Col2 IS NOT NULL 
ORDER BY Dated DESC
)Q2

UNION ALL

SELECT * FROM
(
SELECT TOP 1 'Column3' AS ColumnName
            , Col3 
            , Dated
FROM @t
WHERE Col3 IS NOT NULL 
ORDER BY Dated DESC
)Q3
Run Code Online (Sandbox Code Playgroud)

结果集

????????????????????????????????????????????????
? ColumnName ? Value ?          Dated          ?
????????????????????????????????????????????????
? Column1    ?    20 ? 2013-12-09 00:00:00.000 ?
? Column2    ?   100 ? 2013-12-10 00:00:00.000 ?
? Column3    ?   300 ? 2013-12-08 00:00:00.000 ?
????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)

它返回正确的结果.但我相信它可以通过更简单/更有效的查询来完成 .任何帮助或指针都非常重要

Dam*_*ver 6

几乎是一个简单的UNPIVOT操作,适合ROW_NUMBER选择最新的值.该UNPIVOT自动消除NULL值:

;With Numbered as (
     select *,ROW_NUMBER() OVER (PARTITION BY Col ORDER BY Dated desc) rn
     from @t
     unpivot (Value for Col in (Col1,Col2,Col3)) p
)
select * from Numbered where rn = 1
Run Code Online (Sandbox Code Playgroud)

结果:

ID          Dated                   Value       Col      rn
----------- ----------------------- ----------- -------- --------------------
1           2013-12-09 00:00:00.000 20          Col1     1
1           2013-12-10 00:00:00.000 100         Col2     1
1           2013-12-08 00:00:00.000 300         Col3     1
Run Code Online (Sandbox Code Playgroud)