我想确定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'
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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
中的任何一个的计数表明它在其生命周期中被设置为CODE_GROUP
。