SQL日期选择基于记录状态

时间:2013-04-23 07:30:29

标签: sql-server sql-server-2005

我有一个带有ID和名称的测试主表

TestMaster          
ID  Name        
1   a       
2   b       
3   c   

和testtrans具有ID主ID,开始和结束日期

TestTrans           
ID  MasterID    Statusdate  Outcome
1   1   01/01/2013  Close
2   1   03/01/2013  Open
3   1   06/01/2013  Open
4   1   10/01/2013  Close
5   1   12/01/2013  Open
6   2   10/10/2012  Open
7   2   15/10/2012  Close
8   2   15/10/2012  Open
9   3   15/01/2013  Open
10  3   20/01/2013  Close
11   3  21/01/2013  Open
12  3        25/01/2013         Open

我需要这样的输出
开始日期:应该是记录的状态 结束日期:应基于记录状态。如果状态已关闭,则结束日期将关闭记录的satatusdate,关闭状态之前的所有记录将被视为同一组的一部分

按Masetr ID分组

Output          
Master ID   Start date  end date    
1   01/01/2013  01/01/2013  
1   03/01/2013  10/01/2013  
1   12/01/2013  NULL    
2   10/10/2012  15/10/2012  
2   15/10/2012  Null    
3   15/01/2013  20/01/2013  
3    21/01/2013        Null

1 个答案:

答案 0 :(得分:0)

<强>更新

SET NOCOUNT ON;

DECLARE @temp TABLE
(
      ID INT IDENTITY(1,1)
    , MasterID INT
    , StatusDate datetime
    , Outcome VARCHAR(50)
)

INSERT INTO @temp (MasterID, StatusDate, Outcome)
VALUES 
    (1,   '20130101',  'Close'),
    (1,   '20130103',  'Open'),
    (1,   '20130106',  'Open'),
    (1,   '20130110',  'Close'),
    (1,   '20130112',  'Open'),
    (2,   '20121010',  'Open'),
    (2,   '20121015',  'Close'),
    (2,   '20121015',  'Open'),
    (3,   '20130115',  'Open'),
    (3,   '20130120',  'Close'),
    (3,   '20130121',  'Open'), 
    (3,   '20130125',  'Open')

;WITH data AS 
(
    SELECT 
          t.MasterId
        , StartDate = t.StatusDate
        , EndDate = t.StatusDate
    FROM @temp t
    WHERE OutCome = 'Close'
        AND NOT EXISTS (
            SELECT 1 
            FROM @temp t2
            WHERE t.StatusDate > t2.StatusDate
                AND t.MasterID = t2.MasterID
                AND t2.OutCome = 'Open'
        )

    UNION ALL

    SELECT 
          MasterId
        , StartDate = t.StatusDate
        , a.EndDate 
    FROM @temp t
    OUTER APPLY (
        SELECT EndDate = MAX(StatusDate) 
        FROM @temp a 
        WHERE a.MasterId = t.MasterId
            AND a.Outcome = 'Close'
            AND a.StatusDate > t.StatusDate
    ) a
    WHERE OutCome = 'Open'
        AND (
                NOT EXISTS(
                    SELECT 1 
                    FROM @temp t2
                    WHERE t.StatusDate > t2.StatusDate
                        AND t.MasterID = t2.MasterID
                        AND t.Outcome = t2.Outcome
                ) 
            OR 
                a.EndDate IS NULL
            )
)
SELECT *
FROM data d
WHERE NOT EXISTS(
    SELECT 1
    FROM data d2 
    WHERE d.MasterID = d2.MasterID
        AND d.StartDate > d2.StartDate
        AND d.EndDate IS NULL
        AND d2.EndDate IS NULL
)
ORDER BY 
      d.MasterID
    , d.StartDate
    , d.EndDate