2

我想确定 SQL 数据表中事件的顺序。我的数据是这样排列的,每个标识符-日期-事件组合出现在单独的行上。每个标识符的输出应该是单行,指示 3 个(并且只有 3 个)事件发生的顺序,以及一个标志,指示三个事件中的哪一个曾经发生过。为了指示顺序,我只关心知道第一个事件的类型和最近事件的类型。(例如,ABC=ADAC,因为我只对 A 是第一件事而 C 是最后一件事这一事实感兴趣。)

假设我的数据是:

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'
4

3 回答 3

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 与演示

于 2013-04-28T21:52:54.137 回答
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
于 2013-04-28T22:11:02.477 回答
0

询问:

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_QCODE_GROUP中的每个 ID,具有最小日期的 ID 给出第一个事件,CODE_GROUP而具有最大日期的 ID 给出最后一个事件。

对于 SUB_Q 中的每个 ID,三个CODE_GROUPs 中的任何一个的计数(如果不为零)表明它CODE_GROUP在其生命周期中曾被设置为该值。

见小提琴

于 2013-04-28T21:58:35.737 回答