ROW_NUMBER基于条件的跳过行

时间:2015-10-01 21:04:05

标签: sql-server-2008

我有一个日历表,每个日期都有一个键(整数)列。有效的营业日期分配了密钥;它们按升序排列。问题是,星期六和星期日不被视为有效的营业日期,因此它们的值为“9999”。在这种情况下我想要做的是使用“9999”之后的行作为“Next”值,而不是使用带有“9999”的行。所以,要用伪代码解释,我正在寻找类似的东西:

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

2 个答案:

答案 0 :(得分: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 

答案 1 :(得分:0)

我认为您可以将加入条件更改为import pandas as pd test = pd.Series(["Hey", "I'm", 1.0, "or", 2.0, "floats"]) # Find floats floats = test[test.apply(lambda x: isinstance(x, float))] # Make all strings test_as_strings = test.apply(str) nex以使用日期而不是使用行号。

prev