2015-10-01 52 views
0

我有一個日曆表,每個日期都有一個鍵(整數)列。有效的商業日期被分配密鑰;他們按升序排列。問題是,星期六和星期日不被視爲有效的營業日期,因此它們的值爲「9999」。在這種情況下,我想要做的是使用「9999」之後的行作爲「下一個」值,而不是使用具有「9999」的行。所以,用僞代碼解釋,我正在尋找類似的東西:ROW_NUMBER根據條件跳過行

Case When nex.KEY = '9999' Then skip it and find the nex.KEY row that is not '9999' 
    Else CTE.NEXT_DT 
END AS Next 

我從一個CTE開始,但我對想法持開放態度。這裏是我現在能夠得到的輸出樣本。 「Next」列中的'9999'值是我正在更新的內容。

電流輸出:

rowNum DAY BUSINESS_DT KEY  PREV_DT  NEXT_DT  Previous Next 
3932 Sun 2015-09-13 9999 2015-09-11 2015-09-14 9999 2709 
3933 Mon 2015-09-14 2709 2015-09-11 2015-09-15 9999 2710 
3934 Tue 2015-09-15 2710 2015-09-14 2015-09-16 2709 2711 
3935 Wed 2015-09-16 2711 2015-09-15 2015-09-17 2710 2712 
3936 Thu 2015-09-17 2712 2015-09-16 2015-09-18 2711 2713 
3937 Fri 2015-09-18 2713 2015-09-17 2015-09-21 2712 9999 
3938 Sat 2015-09-19 9999 2015-09-18 2015-09-21 2713 9999 
3939 Sun 2015-09-20 9999 2015-09-18 2015-09-21 9999 2714 
3940 Mon 2015-09-21 2714 2015-09-18 2015-09-22 9999 2715 

所需的輸出:

rowNum DAY BUSINESS_DT KEY  PREV_DT  NEXT_DT  Previous Next 
3932 Sun 2015-09-13 9999 2015-09-11 2015-09-14 9999 2709 
3933 Mon 2015-09-14 2709 2015-09-11 2015-09-15 9999 2710 
3934 Tue 2015-09-15 2710 2015-09-14 2015-09-16 2709 2711 
3935 Wed 2015-09-16 2711 2015-09-15 2015-09-17 2710 2712 
3936 Thu 2015-09-17 2712 2015-09-16 2015-09-18 2711 2713 
3937 Fri 2015-09-18 2713 2015-09-17 2015-09-21 2712 **2714** 
3938 Sat 2015-09-19 9999 2015-09-18 2015-09-21 2713 **2714** 
3939 Sun 2015-09-20 9999 2015-09-18 2015-09-21 9999 2714 
3940 Mon 2015-09-21 2714 2015-09-18 2015-09-22 9999 2715 

下面是我的代碼:

WITH CTE AS 
(
Select 
rowNum = ROW_NUMBER() OVER(ORDER BY d.CALENDAR_DT_ID), 
d.DAY, 
d.KEY, 
d.BUSINESS_DT, 
d.PREV_DT, 
d.NEXT_DT, 
d.HOLIDAY_IN 
FROM CALENDAR_DT d 
) 

SELECT 
CTE.rowNum, 
CTE.DAY, 
CTE.BUSINESS_DT, 
CTE.KEY, 
CTE.PREV_DT, 
CTE.NEXT_DT, 
prev.KEY As Previous, 
nex.KEY As Next 

FROM CTE 
LEFT JOIN CTE prev ON prev.rownum = CTE.rownum - 1 
LEFT JOIN CTE nex ON nex.rownum = CTE.rownum + 1 
ORDER BY BUSINESS_DT 
+0

你表現出你能到目前爲止達到的目標。你是否也可以顯示你想要得到的結果? – DarkKnight

+0

除9999個密鑰行外,KEY總是一個序列號? – DarkKnight

+0

是的。每一個唯一的編號,按升序排列。日曆表從2004年開始,所以現在我們到9/13的2709,9/14的2710,依此類推。對於所有非假期和非週末,每天按鍵遞增1。 – SeanFlynn

回答

1

SQL Fiddle Demo

;WITH CTE1 AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY CALENDAR_DT_ID) AS RN1, 
    DAY1, 
    BUSINESS_DT, 
    KEY1 
    FROM DATESCHART 
) 
,CTE2 AS 
(
    SELECT 1 AS SNO,1 AS RN2,* FROM CTE1 WHERE RN1=1 
    UNION ALL 
    SELECT CASE WHEN C1.KEY1=9999 THEN C2.SNO ELSE C2.SNO+1 END,RN2+1,c1.* 
    FROM CTE1 C1 INNER JOIN CTE2 C2 ON C1.RN1 = C2.RN2 
) 

SELECT C1.DAY1,C1.BUSINESS_DT,C1.KEY1,C3.BUSINESS_DT PREV_DT,C2.BUSINESS_DT NEXT_DT,C3.KEY1 PREVIOUS,C2.KEY1 NEXTK 
FROM CTE2 C1 LEFT JOIN CTE2 C2 ON C1.SNO+1 = C2.SNO AND C2.KEY1<>9999 
      LEFT JOIN CTE2 C3 ON C1.SNO-1 = C3.SNO AND C3.KEY1<>9999 
WHERE C1.RN2>1 
+0

加一個小提琴。完美的作品。謝謝! – SeanFlynn

+0

@ SeanFlynn:乾杯! – DarkKnight

0

我想你可以改變的加盟條件nexprev到使用日期而不是使用行號。

WITH CTE AS 
(
Select 
    rowNum = ROW_NUMBER() OVER(ORDER BY d.CALENDAR_DT_ID), 
    d.DAY, 
    d.KEY, 
    d.BUSINESS_DT, 
    d.PREV_DT, 
    d.NEXT_DT, 
    d.HOLIDAY_IN 
FROM CALENDAR_DT d 
) 
SELECT 
    CTE.rowNum, 
    CTE.DAY, 
    CTE.BUSINESS_DT, 
    CTE.KEY, 
    CTE.PREV_DT, 
    CTE.NEXT_DT, 
    prev.KEY As Previous, 
    nex.KEY As Next 
FROM CTE 
LEFT JOIN CTE prev 
ON CTE.PREV_DT = prev.BUSINESS_DT 
LEFT JOIN CTE nex 
ON CTE.NEXT_DT = nex.BUSINESS_DT 
ORDER BY BUSINESS_DT 
+0

你試過這個嗎?它不那麼複雜,性能會更好。您的數據顯示您的下一個和前一個日期已經指向您所需的商業日期密鑰。 –