2

SQL データ テーブル内のイベントの順序を特定したいと考えています。私のデータは、各識別子、日付、イベントの組み合わせが個別の行に表示されるように配置されています。出力は、識別子ごとに 1 行で、3 つの (そして 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

demo を使用した SQL Fiddle

于 2013-04-28T21:52:54.137 に答える
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

説明:

最初に、元のデータを ID でグループ化する SUB_Q という単純なサブクエリがあり、他のすべてはその上で行われます。

SUB_Q のすべての ID について、CODE_GROUP最小日付の ID は最初のイベントを示し、CODE_GROUP最大日付の ID は最後のイベントを示します。

SUB_Q のすべての ID について、3 つのいずれかのカウントが0 でない場合は、そのライフ サイクル中にそのID にCODE_GROUP設定されたことがあることを示します。CODE_GROUP

フィドルを見る

于 2013-04-28T21:58:35.737 に答える