2011-12-16 72 views
5

我有如下表:遞歸CTE - 鞏固開始和結束日期

row_num customer_status effective_from_datetime 
------- ------------------ ----------------------- 
1  Active    2011-01-01 
2  Active    2011-01-02 
3  Active    2011-01-03 
4  Suspended   2011-01-04 
5  Suspended   2011-01-05 
6  Active    2011-01-06 

,我試圖實現以下目的,從而以相同的狀態連續行被從併合併成一排與有效日期範圍:

customer_status effective_from_datetime effective_to_datetime 
--------------- ----------------------- --------------------- 
Active   2011-01-01    2011-01-04 
Suspended  2011-01-04    2011-01-06 
Active   2011-01-06    NULL 

我可以得到一個遞歸CTE輸出基於下一行的正確effective_to_datetime,但我有麻煩的合併範圍。

代碼,以生成樣本數據:

CREATE TABLE #temp 
(
row_num INT IDENTITY(1,1), 
customer_status VARCHAR(10), 
effective_from_datetime DATE 
) 

INSERT INTO #temp 
VALUES 
('Active','2011-01-01') 
,('Active','2011-01-02') 
,('Active','2011-01-03') 
,('Suspended','2011-01-04') 
,('Suspended','2011-01-05') 
,('Active','2011-01-06') 
+0

哦,我不想使用遊標或循環,因爲計劃是在視圖中使用這個邏輯。 – shakedown7 2011-12-16 15:37:36

+0

如果您沒有日期條目,該怎麼辦?這應該被視爲序列中的差距嗎?例如假設'('Active','2011-01-02')行不在那裏? – 2011-12-16 15:58:43

回答

8

編輯 SQL更新根據註釋。

WITH 
    group_assigned_data AS 
(
    SELECT 
    ROW_NUMBER() OVER (PARTITION BY customer_status ORDER BY effective_from_date) AS status_sequence_id, 
    ROW_NUMBER() OVER (       ORDER BY effective_from_date) AS sequence_id, 
    customer_status, 
    effective_from_date 
    FROM 
    your_table 
) 
, 
    grouped_data AS 
(
    SELECT 
    customer_status, 
    MIN(effective_from_date) AS min_effective_from_date, 
    MAX(effective_from_date) AS max_effective_from_date 
    FROM 
    group_assigned_data 
    GROUP BY 
    customer_status, 
    sequence_id - status_sequence_id 
) 
SELECT 
    [current].customer_status, 
    [current].min_effective_from_date  AS effective_from, 
    [next].min_effective_from_date   AS effective_to 
FROM 
    grouped_data AS [current] 
LEFT JOIN 
    grouped_data AS [next] 
    ON [current].max_effective_from_date = [next].min_effective_from_date + 1 
ORDER BY 
    [current].min_effective_from_date 

這不是遞歸的,但這可能是一件好事。


它不應對數據缺口。爲了解決這個問題,你可以創建一個日曆表,每一個相關的日期,並加入這個日曆表以填補'未知'狀態的缺失日期,然後運行查詢。 (事實上​​,你應該做CTE,CTE被上面的CTE使用)。

目前...
- 如果連續2失蹤,也不會改變這一結果
- 如果連續3失蹤,第一行的END_DATE會改變

可確定

不同的行爲通過準備您的數據或其他方法。我們需要知道您需要的業務邏輯。


如果任何一個日期可以有多個狀態條目,你需要定義你想要它遵循什麼邏輯。目前的行爲是不確定的,但您可以將其修改爲只需將customer_status添加到ROW_NUMBER()的ORDER BY部分即可。