2012-03-09 164 views
0

我一直在創造的日期範圍,但在某些情況下,有一個問題:問題的日期範圍內創建

這是我有:TABLE_1

date   customer_id  status  total 
----   ------------- -------- ------- 
20120201   1    a   10 
20120202   1    a   20 
20120203   1    b   20 
20120204   1    b   20 
20120205   1    a   20 
20120206   1    a   20 
20120201   2    d   30 
20120202   2    e   40 

我的程序執行後,我有這樣的:TABLE_2

customer_id  status  start_date  end_date 
------------- -------- -----------  --------- 
    1    a   20120201  NULL 
    1    b   20120203  20120131 
    2    d   20120201  20120201 
    2    e   20120202  NULL 

但是,這是我想要的,與日期範圍表基於CUSTOMER_ID和狀態(END_DATE代表與最近的日期登記):TABLE_3

customer_id  status  start_date  end_date 
------------- -------- -----------  --------- 
    1    a   20120201  20120202 
    1    b   20120203  20120204 
    1    a   20120205  NULL 
    2    d   20120201  20120201 
    2    e   20120202  NULL 

我的存儲過程是這樣的:

;WITH TEMP AS (
SELECT 
    Date 
    customer_id 
    status 
FROM table_1 
GROUP BY 
    date, 
    customer_id, 
    status 
) 
,TEMP2 AS (
    SELECT 
     ID = ROW_NUMBER() OVER(PARTITION BY customer_id ORDER BY MAX(date) DESC), 
     start_date = MIN(date), 
     end_date = MAX(date), 
     [customer_id], 
     [status] 
    FROM TEMP 
    GROUP BY 
     [customer_id], 
     [status] 
) 
SELECT 
    A.customer_id, 
    A.status, 
    A.start_date, 
    end_date  = DATEADD(DAY,-1,B.start_date) 
FROM TEMP2 A 
LEFT JOIN TEMP2 B 
    ON A.customer_id = B.customer_id 
    AND A.ID = B.ID + 1 

我知道我的錯誤是在創建CTE TEMP2的,因爲這個代碼不容對於狀態的CUSTOMER_ID有兩個出現在不同的歧視時間範圍,「按組」一句

基礎上,我不能弄清楚如何做到這一點...

+0

在您的「我想要的」列中,爲什麼客戶id = 1 status = a start date = 20120205的行沒有20120206作爲結束日期?你怎麼能知道一個具有相同客戶和地位的記錄「相互配合」?同樣,在你想要的結果中,爲什麼客戶2的狀態d得到結束日期,並且客戶2的狀態e沒有結束日期? 「總計」列與您想要的結果有任何關聯嗎? – 2012-03-11 13:37:24

+0

這些就是你按上述順序排列的問題的答案:----- 1。因爲是customer_id = 1的最後一個寄存器,所以這代表了customer_id的最新狀態,如果你想要這樣看,NULL的含義等於一個getdate()表達式----- 2.這個想法代表不同客戶的狀態變化時間_id ----- 3。總數沒有任何相關性 – 2012-03-13 16:20:34

回答

0

試試這個。希望它現在可以工作。

DECLARE @table_1 TABLE ( 
    date DATETIME, 
    customer_id INT, 
    status CHAR(1), 
    total INT 
) 

INSERT @table_1 (date, customer_id, status, total) 
VALUES 
('20120201', 1, 'a', 10), 
('20120202', 1, 'a', 20), 
('20120203', 1, 'b', 20), 
('20120204', 1, 'b', 20), 
('20120205', 1, 'a', 20), 
('20120206', 1, 'a', 20), 
('20120201', 2, 'd', 30), 
('20120202', 2, 'e', 40) 



;WITH CTE_1 AS ( 
    SELECT 
     customer_id, 
     status, 
     date, 
     ROW_NUMBER() OVER(PARTITION BY customer_id ORDER BY date ASC) AS seq 
    FROM @table_1  
), 
CTE_2 AS (
    SELECT 
     customer_id, 
     status, 
     date, 
     seq, 
     1 AS flg, 
     1 AS seq2 
    FROM CTE_1 
    WHERE 
     seq = 1 

    UNION ALL 

    SELECT 
     CTE_1.customer_id, 
     CTE_1.status, 
     CTE_1.date, 
     CTE_1.seq, 
     CASE WHEN CTE_2.status = CTE_1.status THEN 0 ELSE 1 END, 
     CASE WHEN CTE_2.status = CTE_1.status THEN CTE_2.seq2 ELSE CTE_2.seq2 + 1 END 
    FROM CTE_1 
    INNER JOIN CTE_2 
     ON CTE_1.customer_id = CTE_2.customer_id 
      AND CTE_1.seq = CTE_2.seq + 1 
) 
SELECT 
    st.customer_id, 
    st.status, 
    st.date AS start_date, 
    DATEADD(DAY, -1, en.date) AS end_date 
FROM CTE_2 AS st 
LEFT JOIN CTE_2 AS en 
    ON st.customer_id = en.customer_id 
     AND st.seq2 = en.seq2 - 1 
     AND en.flg = 1 
WHERE 
    st.flg = 1 
ORDER BY 
    st.customer_id, 
    st.seq2 
+0

對於這種特殊情況,答案接近正確,但並不代表我需要的東西。我將盡力解釋更多細節。 @ table_1是每個customer_id都有連續日期範圍的表,但狀態字段可以在這個連續的範圍內變化。我需要在table_1中創建一個表格,用於顯示時間狀態的變化,包括start_date和end_date。謝謝! – 2012-03-13 16:59:48

+0

明白了!請檢查更新。 – 2012-03-13 17:22:51

+0

這是正確的! – 2012-03-13 21:44:17