2013-03-05 100 views
4

我試圖獲取最近的記錄並找到非匹配的非NULL。問題是我的子查詢返回多個結果。獲取最近的非空記錄

數據集

| ID |   DD | SIG_ID |  DCRP | 
---------------------------------------- 
| 1 | 2010-06-01 |  1 | Expert | 
| 2 | 2010-09-01 |  1 | Expert | 
| 3 | 2010-12-01 |  1 | Expert | 
| 4 | 2010-12-01 |  1 | Expert II | 
| 5 | 2011-03-01 |  1 | Expert II | 
| 6 | 2011-06-01 |  1 | (null) | 
| 7 | 2010-06-01 |  2 | Senior | 
| 8 | 2010-09-01 |  2 | Senior | 
| 9 | 2010-09-01 |  2 | Senior | 
| 10 | 2010-12-01 |  2 | Senior II | 
| 11 | 2011-03-01 |  2 | (null) | 
| 12 | 2011-03-01 |  2 | Senior | 
| 13 | 2010-06-01 |  3 | (null) | 
| 14 | 2010-09-01 |  3 | (null) | 
| 15 | 2010-12-01 |  3 | (null) |

查詢

SELECT a.sig_id, a.id, 
    CASE 
    WHEN b.dcrp IS NULL 
     THEN 
     (SELECT dcrp 
     FROM tbl 
     WHERE sig_id = a.sig_id 
      AND id < a.id 
      AND dcrp IS NOT NULL) 
     ELSE b.dcrp 
    END AS dcrp 
FROM 
    (SELECT sig_id, MAX(id) id 
    FROM tbl 
    GROUP BY sig_id) a 
LEFT JOIN 
    (SELECT id, dcrp 
    FROM tbl 
    WHERE dcrp IS NOT NULL) b ON b.id = a.id 

期望的結果

獲取最新dcrp每個sig_id

| ID |   DD | SIG_ID |  DCRP | 
---------------------------------------- 
| 5 | 2011-03-01 |  1 | Expert II | 
| 12 | 2011-03-01 |  2 | Senior | 
| 15 | 2010-12-01 |  3 | (null) |

SQL Fiddle

+0

每'sig_ID'最近? – 2013-03-05 16:28:08

+0

@ypercube正確。剛剛更新。 – Kermit 2013-03-05 16:28:23

回答

10

您可以使用以下方法:

;WITH CTE AS 
(
    SELECT *, ROW_NUMBER() OVER(PARTITION BY SIG_ID 
           ORDER BY CASE WHEN DCRP IS NOT NULL THEN 0 ELSE 1 END, 
           DD DESC) RN 
    FROM tbl 
) 
SELECT * 
FROM CTE 
WHERE RN = 1 

而且fiddle

+0

+1 - 打敗我吧。 CTE來拯救! – JNK 2013-03-05 16:32:22

-2

在SQLFiddle查詢失敗,因爲子查詢返回超過1行。
添加TOP 1修復。請檢查它是否正常。

THEN 
     (SELECT TOP 1 dcrp 
     FROM tbl 
     WHERE sig_id = a.sig_id 
      AND id < a.id 
      AND dcrp IS NOT NULL) 
+0

下調時,請說明原因。我不介意刪除答案。 – shahkalpesh 2013-03-05 20:38:17

2
;with si as (
    select distinct sig_id from tbl 
) 

select * 
from si 
cross apply (select top 1 * from tbl where si.sig_id=tbl.sig_id order by case when dcrp is null then 1 else 0 end asc,dd desc) sii 

,並與小提琴手: http://sqlfiddle.com/#!3/8e267/2/0

+3

這給出了正確的結果,但獨特+交叉應用產生比row_number變化更昂貴的計劃。 – 2013-03-05 16:41:43

+1

@AaronBertrand你太過分了解。 – Kermit 2013-03-05 17:25:37

+0

@AarolamaBluenk bwahaha我想你一定讓我和別人混淆。 :-) – 2013-03-05 17:26:41