Sql 如何从内部查询中选择第一条记录?

Sql 如何从内部查询中选择第一条记录?,sql,oracle,Sql,Oracle,我有一个表(称之为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

我有一个表(称之为
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
OBJ_ID     FOO_TIME      BAR_TIME

1          10/10/2010    01/05/2011
2          01/01/2012    08/09/2012
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'))
重要提示-我的
事件ID
列未排序

我想执行一个SQL查询来显示FOO事件和bar事件之间的时间差,如下所示:

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
OBJ_ID     FOO_TIME      BAR_TIME

1          10/10/2010    01/05/2011
2          01/01/2012    08/09/2012
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'))
当我最初编写此查询时,我的
事件\u ID
是有序的,所以我做了如下操作:

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
OBJ_ID     FOO_TIME      BAR_TIME

1          10/10/2010    01/05/2011
2          01/01/2012    08/09/2012
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'))
但是,由于我将不讨论的其他项目约束,我的
事件\u ID
不再按时间顺序排列,因此此查询不起作用。我还尝试按E3.EVENT\u DATE执行一个
排序,并选择其中的row\u number()=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;

我假设您知道如何计算日期差,因为您已经有了一个曾经有效的查询。

因此您需要FOO事件及其后续的BAR事件。尝试“lead”分析函数以获得后续的条

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

你可以在我的数据库中做一个min(E3.EVENT\u DATE),可能会有一个完整的FOO和BAR事件流。我需要为每个FOO显示下一个最近条的时间。您的第二个建议对我不起作用,因为我需要加入obj_events表,以便对日期进行算术运算。