2013-04-28 26 views
2

我想,以確定在SQL數據表事件的排序。我的數據排列成每個標識符日期事件組合都顯示在單獨的行上。輸出應該是每個標識符的單個行,表示3個事件發生的順序(以及3個事件發生的順序),以及指示出現三個事件中的哪個事件的標誌。爲了表示順序,我只關心第一個事件的類型和最近事件的類型。 (因此,例如,ABC = ADAC,因爲我只是一個事實,即A是第一件事情和C是最後的事情感興趣。)確定SQL事件的日期排序(爲每個組)

假設我的數據是:

CREATE TABLE #ABC 
(ID INT NOT NULL, 
CODE_DATE DATE NOT NULL, 
CODE_GROUP VARCHAR(10) NULL) 

INSERT INTO #ABC VALUES (1,'20000-01-01','APPROVED') 
INSERT INTO #ABC VALUES (1,'20001-01-01','DENIED') 
INSERT INTO #ABC VALUES (1,'20003-01-01','ON HOLD') 
INSERT INTO #ABC VALUES (1,'20002-01-01','APPROVED') 
INSERT INTO #ABC VALUES (2,'20008-01-01','DENIED') 
INSERT INTO #ABC VALUES (2,'20004-01-01','DENIED') 
INSERT INTO #ABC VALUES (3,'20006-01-01','ON HOLD') 
INSERT INTO #ABC VALUES (3,'20005-01-01','APPROVED') 
INSERT INTO #ABC VALUES (3,'20009-01-01','DENIED') 
INSERT INTO #ABC VALUES (4,'20001-01-01','ON HOLD') 
INSERT INTO #ABC VALUES (4,'20004-01-01','ON HOLD') 
INSERT INTO #ABC VALUES (4,'20007-01-01','DENIED') 
INSERT INTO #ABC VALUES (5,'20005-01-01','ON HOLD') 
INSERT INTO #ABC VALUES (5,'20008-01-01','ON HOLD') 
INSERT INTO #ABC VALUES (5,'20009-01-01','APPROVED') 

然後將所需的輸出是:

ID RESULT     EVER_APPROVED EVER_DENIED EVER_ON_HOLD 
1 'APPROVED THEN ON HOLD' 'Y'    'Y'   'Y' 
2 'DENIED'    'N'    'Y'   'N' 
3 'APPROVED THEN DENIED' 'Y'    'Y'   'Y' 
4 'ON HOLD THEN DENIED' 'N'    'Y'   'Y' 
5 'ON HOLD THEN APPROVED' 'Y'    'N'   'Y' 
+0

嘗試任何東西,或..? – jurgenreza 2013-04-28 21:05:39

+0

我真的被卡住了。通常我會使用SAS數據步驟,但不再有權訪問SAS。我猜想我可以在日期字段上使用MIN和MAX來識別每個ID的第一個最後事件,但我不確定。 – user1126915 2013-04-28 21:21:24

回答

1

這是給你的數據在正確的結果:

with ABCOrdered as 
(
    select * 
    , FirstEvent = row_number() over (partition by ID order by CODE_DATE) 
    , LastEvent = row_number() over (partition by ID order by CODE_DATE desc) 
    from ABC 
) 
select f.ID 
    , [RESULT] = case 
    when f.CODE_GROUP = l.CODE_GROUP or l.CODE_GROUP is null then f.CODE_GROUP 
    else f.CODE_GROUP + ' THEN ' + l.CODE_GROUP 
    end 
    , EVER_APPROVED = case 
    when exists (select 1 from ABC where l.ID = ABC.ID and ABC.CODE_GROUP = 'APPROVED') then 'Y' 
    else 'N' 
    end 
    , EVER_DENIED = case 
    when exists (select 1 from ABC where l.ID = ABC.ID and ABC.CODE_GROUP = 'DENIED') then 'Y' 
    else 'N' 
    end 
    , EVER_ON_HOLD = case 
    when exists (select 1 from ABC where l.ID = ABC.ID and ABC.CODE_GROUP = 'ON HOLD') then 'Y' 
    else 'N' 
    end 
from ABCOrdered f 
    left join ABCOrdered l on f.ID = l.ID and l.LastEvent = 1 
where f.FirstEvent = 1 
order by f.ID 

SQL Fiddle with demo

+0

謝謝!這對我的數據有效。 – user1126915 2013-04-28 22:40:29

0

QUERY:

SELECT 
    ID, 
    (SELECT CODE_GROUP FROM ABC WHERE ID = SUB_Q.ID AND CODE_DATE = SUB_Q.MIN_DATE) AS FIRST_EVENT, 
    (SELECT CODE_GROUP FROM ABC WHERE ID = SUB_Q.ID AND CODE_DATE = SUB_Q.MAX_DATE) AS LAST_EVENT, 
    EVER_APPROVED = CASE WHEN (SELECT COUNT(*) FROM ABC WHERE ID = SUB_Q.ID AND CODE_GROUP = 'APPROVED') = 0 THEN 'N' ELSE 'Y' END, 
    EVER_DENIED = CASE WHEN (SELECT COUNT(*) FROM ABC WHERE ID = SUB_Q.ID AND CODE_GROUP = 'DENIED') = 0 THEN 'N' ELSE 'Y' END, 
    EVER_ONHOLD = CASE WHEN (SELECT COUNT(*) FROM ABC WHERE ID = SUB_Q.ID AND CODE_GROUP = 'ON HOLD') = 0 THEN 'N' ELSE 'Y' END 
FROM 
    (SELECT 
    ID, 
    MIN(CODE_DATE) AS MIN_DATE, 
    MAX(CODE_DATE) AS MAX_DATE 
    FROM 
    ABC 
    GROUP BY 
    ID) AS SUB_Q 

結果:

ID FIRST_EVENT LAST_EVENT EVER_APPROVED EVER_DENIED EVER_ONHOLD 
1 APPROVED ON HOLD  Y    Y   Y 
2 DENIED  DENIED  N    Y   N 
3 APPROVED DENIED  Y    Y   Y 
4 ON HOLD  DENIED  N    Y   Y 
5 ON HOLD  APPROVED Y    N   Y 

說明:

首先,我有一個簡單的子查詢稱爲SUB_Q它能將原始數據通過ID和其他一切完成那個。

對於SUB_Q中的每個ID,CODE_GROUP與最小日期,給出第一個事件和CODE_GROUP與最大日期,給最後一個事件。

對於SUB_Q每一個ID,的任何三個CODE_GROUP S的計數,如果不爲零,顯示這是它的生命週期中不斷設置爲CODE_GROUP

SEE FIDDLE

1

這裏是另一種方式來做到這一點:

;WITH cteMaxMin As 
(
    SELECT 
     ID, 
     Max(CODE_DATE+':'+CODE_GROUP) As MaxDt, 
     Min(CODE_DATE+':'+CODE_GROUP) As MinDt, 
     Max(Case When CODE_GROUP='APPROVED' Then 'Y' Else Null End) As Apd, 
     Max(Case When CODE_GROUP='DENIED' Then 'Y' Else Null End) As Dnd, 
     Max(Case When CODE_GROUP='ON HOLD' Then 'Y' Else Null End) As Ohd 
    FROM  #ABC 
    GROUP BY ID 
) 
SELECT 
    ID, 
    SUBSTRING(MaxDt, 13, LEN(MaxDt)) 
    + COALESCE(' THEN '+SUBSTRING(MinDt, 13, LEN(MinDt)), '') As RESULT, 
    COALESCE(Apd, 'N')    As EVER_APPROVED, 
    COALESCE(Dnd, 'N')    As EVER_DENIED, 
    COALESCE(Ohd, 'N')    As EVER_ON_HOLD 
FROM cteMaxMin