我有一个记录每个ID的事件日期的表。每个事件都有一个类型,每个事件类型和ID可能有零个或多个注册日期。
我需要生成一个包含每个不同ID的结果集,以及第一个开始日期,最后修复日期和最后结束日期。这很简单。但我还需要为每条记录选择参考代码。这部分我似乎无法在同一个查询中处理。
with example_data as(
select 'A' as id, 'START' as t, date '2017-01-01' as d, '18' as ref from dual union all
select 'A' as id, 'WHATEV' as t, date '2017-01-02' as d, '12' as ref from dual union all
select 'A' as id, 'CRASH' as t, date '2017-01-05' as d, '17' as ref from dual union all
select 'A' as id, 'REPAIR' as t, date '2017-01-06' as d, '01' as ref from dual union all
select 'A' as id, 'CRASH' as t, date '2017-01-10' as d, '20' as ref from dual union all
select 'A' as id, 'REPAIR' as t, date '2017-01-11' as d, '07' as ref from dual union all
select 'A' as id, 'END' as t, date '2017-01-12' as d, '14' as ref from dual union all
select 'B' as id, 'START' as t, date '2017-01-01' as d, '24' as ref from dual union all
select 'B' as id, 'END' as t, date '2017-01-10' as d, '28' as ref from dual
-- Primary key(id, t, d)
)
select id
,min(case when t = 'START' then d end) as start_date
,max(case when t = 'END' then d end) as end_date
,max(case when t = 'REPAIR' then d end) as repair_date
from example_data
where t in('START', 'END', 'REPAIR')
group
by id;
ID START_DATE END_DATE REPAIR_DATE
-- ---------- ---------- -----------
A 2017-01-01 2017-01-12 2017-01-11
B 2017-01-01 2017-01-10
这是我尝试从相应的记录中包含ref代码,但由于某种原因,repair_ref为null。
select id
,min(case when t = 'START' then ref end) keep (dense_rank first order by d asc) as start_ref
,min(case when t = 'END' then ref end) keep (dense_rank first order by d desc) as end_ref
,min(case when t = 'REPAIR' then ref end) keep (dense_rank first order by d desc) as repair_ref
from example_data
where t in('START', 'END', 'REPAIR')
group
by id;
这是我尝试的输出。对于id = A,我期待repair_ref ='07'。我做错了什么?
ID START_REF END_REF REPAIR_REF
-- --------- ------- ----------
A 18 14
B 24 28
答案 0 :(得分:2)
这有点复杂。问题是keep
正在查看所有记录。所以,我认为你可以做到:
select id,
min(case when t = 'START' then d end) keep (dense_rank first
order by (case when t = 'START' then d end) asc) as start_date,
max(case when t = 'END' then d end) keep (dense_rank first
order by (case when t = 'END' then d end) desc nulls last) as end_date,
max(case when t = 'REPAIR' then d end) keep (dense_rank first
order by (case when t = 'REPAIR' then d end) desc nulls last) as repair_date
from example_data
where t in ('START', 'END', 'REPAIR')
group by id;