2014-01-10 72 views
1

我有一種情況,我試圖從所有列中獲取最後一個非空值。這裏是一些數據來演示puposes。從所有列中獲取最後一個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 ║ 
╚════╩══════╩══════╩══════╩═════════════════════════╝ 

我建立了一個查詢返回所需的結果。但是想知道是否有更高性能的這種做法。由於這種方式,我每次希望找到獲得這些結果的更有效方法時,都在嘲笑整個表格。

我的查詢

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 

結果集

╔════════════╦═══════╦═════════════════════════╗ 
║ 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 ║ 
╚════════════╩═══════╩═════════════════════════╝ 

它返回正確的結果。但我確信它可以通過更簡單/高效的查詢完成。任何幫助或指針是多少appericiated

回答

5

差不多一個簡單的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 

結果:

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 
+0

你是一個明星達米安你的查詢是最便宜的我剛剛比較了所有三種解決方案,礦山55%,Upendra的28%和你的17%的批次。乾杯朋友:) –

2

我認爲,在垂直行格式的UNION選擇是好,但如果你需要它在水平列的格式,那麼你可以使用自加入像下面

SELECT top 1 t1.Col1, t2.Col2, t3.col3 
FROM @t t1 
inner join @t t2 on t2.col2 is not null 
inner join @t t3 on t3.col3 is not null 
where t1.col1 is not null 
order by t1.dated desc 
+0

謝謝您的效應初探,更簡單,更好的解決方案,然後我的,它​​是拉動正確的數據,但你可以在我的結果看設置我實際上是旋轉結果。會友好地更新回答,以便得到與我期望的輸出中所示完全相同的結果。 –

相關問題