2012-03-09 168 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