我有一张桌子(称之为OBJ_EVENTS
),如下所示:
EVENT_ID OBJ_ID EVENT_DATE EVENT_TYPE
500 1 10/10/2010 FOO
497 1 01/05/2011 BAR
714 1 01/06/2011 BAZ
1700 2 01/01/2012 FOO
57 2 08/09/2012 BAR
12 2 08/10/2010 BAZ
重要提示 - 我的EVENT_ID
列未订购
我想执行一个SQL查询来显示FOO事件和bar事件之间的时差,如下所示:
OBJ_ID FOO_TIME BAR_TIME
1 10/10/2010 01/05/2011
2 01/01/2012 08/09/2012
当我最初编写此查询时,我的EVENT_ID
已被订购,所以我做了类似的事情:
SELECT E1.OBJ_ID,
E1.EVENT_DATE AS FOO_TIME,
E2.EVENT_DATE AS BAR_TIME
FROM OBJ_EVENTS E1
JOIN OBJ_EVENTS E2
ON (E2.EVENT_ID = (SELECT MIN(EVENT_ID)
FROM OBJ_EVENTS E3
WHERE E3.OBJ_ID = E1.OBJ_ID
AND E3.EVENT_DATE >= E1.EVENT_DATE
AND E3.EVENT_TYPE = 'BAR'))
但是,由于我不会涉及的其他项目限制,我的EVENT_ID
不再按时间顺序排序,因此此查询不起作用。我也试过做order by E3.EVENT_DATE
并选择row_number()= 1的位置,但这也不起作用。 Oracle抛出错误。
帮助!!!
答案 0 :(得分:1)
如果每个obj_id
只有一个foo事件和一个bar事件,那么您的查询过于复杂:
select ef.obj_id, ef.event_date as event_date_foo, eb.event_date as event_date_bar
from obj_events ef join
obj_events eb
on ef.obj_id = eb.obj_id and
ef.event_type = 'FOO' and
eb.event_type = 'BAR';
如果有多次出现,您需要确定自己想要的内容。这个是第一次出现:
select e.obj_id,
min(case when e.event_type = 'FOO' then event_date end) as event_date_foo,
min(case when e.event_type = 'BAR' then event_date end) as event_date_bar
from obj_events e
group by e.obj_id;
我假设您知道如何区分日期,因为您已经有了一个曾经有效的查询。
答案 1 :(得分:1)
所以你想要FOO事件及其随后的BAR事件。尝试使用“引导”分析函数来获得后续的BAR。
select event_type, next_type, event_date, next_date, next_date - event_date from (
select obj_id, event_date, event_type,
lead(event_type) over (partition by obj_id order by event_date) next_type,
lead(event_date) over (partition by obj_id order by event_date) next_date
from
event_test
where event_type in ('FOO', 'BAR')
) where event_type = 'FOO' and next_type='BAR'
会给你这个:
1 1 FOO BAR 10/10/2010 1/5/2011 87
2 2 FOO BAR 1/1/2012 8/9/2012 221