我在下表中有这个
App No EventCode Event Date
---------------------------------------------------------
1 A 2010-01-01
1 B 2010-01-02
1 C 2010-01-03
1 A 2010-01-10
2 A 2010-01-04
2 C 2010-01-05
2 B 2010-01-06
3 A 2010-01-01
3 D 2010-01-11
4 A 2011-01-01
4 D 2011-01-02
4 C 2011-03-03
我需要确定App No是否至少有一个事件A,然后是事件C,而中间没有事件B。请告知是否可以使用按应用程序编号分组。我已经有一个复杂的查询,可以按应用程序编号分组以计算各种值。我需要将这一点与之整合。
结果表应类似于
[App No] [A Immediately Followed By C] [Max A date]
-------------------------------------------------------
1 0 2010-01-10
2 1 2010-01-04
3 0 2010-01-01
4 1 2011-01-01
答案 0 :(得分:1)
我不记得通过聚合来解决此问题的方法,但是您可以对SQL Server 2008+使用LEAD()(可以在SQL SERVER 2012+中使用)或ROW_NUMBER()。
这是示例数据和临时表。
...阅读完有关问题的评论后,更新版本:
CREATE TABLE #table_name (
app_no int,
event_code char(1),
event_date date
);
insert into #table_name
values
(1,'A',GETDATE()-100),
(1,'B',GETDATE()-10),
(1,'C',GETDATE()-1),
(2,'A',GETDATE()+10),
(2,'A',GETDATE()+1),
(2,'D',GETDATE()),
(2,'C',GETDATE()+10),
(3,'A',GETDATE()),
(3,'C',GETDATE()+100)
select *
,ROW_NUMBER() over (partition by 1 order by app_no) as rowid
into #table_name2
from #table_name
where event_code in ('A','B','C')
select org.app_no
,org.event_code
,case
when rez2.event_code is not null then 1
else 0
end as 'A followed by C'
,case
when rez2.max_date is not null then rez2.max_date
else org.event_date
end as 'Max A date'
from #table_name2 org
left outer join (
select t1.*,d.max_date
from #table_name2 t1
inner join #table_name2 t2 on t2.rowid=t1.rowid+1
left outer join
(
select app_no,event_code,MAX(event_date) as max_date
from #table_name
group by app_no,event_code
)d on d.app_no=t1.app_no and d.event_code=t1.event_code
where t1.event_code='A' and t2.event_code='C'
)rez2 on rez2.app_no=org.app_no and rez2.event_code=org.event_code and rez2.event_date=org.event_date
where org.event_code='A'
drop table #table_name
drop table #table_name2
答案 1 :(得分:1)
为此,您应使用lead()
进行汇总和过滤:
select appno,
(case when max(case when eventcode = 'A' and next_ec = 'C' then 1 else 0 end) > 0
then 1 else 0
end) as flag,
max(case when eventcode = 'A' then date end) as max_a_date
from (select t.*,
lead(eventcode) over (partition by appno order by date) as next_ec
from t
where eventcode <> 'B'
) t
group by appno;
编辑:
在SQL Server 2008中,您可以执行以下操作:
select appno,
(case when max(case when eventcode = 'A' and next_ec = 'C' then 1 else 0 end) > 0
then 1 else 0
end) as flag,
max(case when eventcode = 'A' then date end) as max_a_date
from (select t.*,
t2.eventcode as next_ec
from t outer apply
(select top (1) t2.*
from t t2
where t2.appno = t.appno and t2.date > t.date
order by t2.date desc
) tnext
where eventcode <> 'B'
) t
group by appno;
答案 2 :(得分:0)
;WITH cte
AS
(
SELECT tn.app_no
,tn.event_code
,tn.event_date
,LEAD(tn.event_code) OVER (PARTITION BY tn.app_no ORDER BY tn.event_date) NextEvent
FROM <Your_Table> AS tn
)
SELECT app_no
,MAX(CASE WHEN cte.NextEvent='C'
THEN 1
ELSE 0
END) AS [A Immediately Followed By C]
,MAX(event_date) event_date
FROM cte
WHERE event_code='A'
GROUP BY app_no