Oracle: associate a date with the earliest in a list without reuse Oracle: associate a date with the earliest in a list without reuse oracle oracle

Oracle: associate a date with the earliest in a list without reuse


with t1(ENC_ID, CONTACT, EVENT_TIME) as(  select 13991333,    1,   '08/13/2012 22:00:36' from dual union all  select 13991333,    1,   '08/13/2012 22:25:21' from dual union all  select 13991333,    1,   '08/13/2012 22:26:14' from dual union all  select 13991333,    1,   '08/13/2012 22:36:42' from dual union all  select 13991333,    2,   '08/13/2012 22:29:40' from dual),t2(ENC_ID,CONTACT,EVENT_TIME) as(  select 13991333,    1,   '08/13/2012 22:25:40' from dual union all  select 13991333,    1,   '08/13/2012 22:29:31' from dual union all  select 13991333,    1,   '08/13/2012 22:30:47' from dual union all  select 13991333,    1,   '08/13/2012 22:31:35' from dual union all  select 13991333,    1,   '08/13/2012 22:31:49' from dual union all  select 13991333,    2,   '08/13/2012 22:31:14' from dual)select enc_id     , contact     , req     , min(res) resp  from (select q.enc_id             , q.contact             , q.req             , case                   when resp > req then nth_value(q.resp, q.gid) over(partition by q.enc_id, q.contact, gid order by q.req, q.gid)               end res         from (select t1.enc_id                    , t1.contact                    , t1.event_time req                    , dense_rank() over (partition by t1.enc_id, t1.contact order by t1.event_time) gid                    , t2.event_time resp                 from t1                 left outer join t2                   on (t1.enc_id = t2.enc_id   and                       t1.contact = t2.contact)                order by 1,2,3,5               ) q         )group by enc_id       , contact       ,  reqorder by enc_id       , contact       ,  req

Result:

 ENC_ID    CONTACT     REQ                 RESP---------- ----------  ------------------- -------------------  13991333          1  08/13/2012 22:00:36 08/13/2012 22:25:40  13991333          1  08/13/2012 22:25:21 08/13/2012 22:29:31  13991333          1  08/13/2012 22:26:14 08/13/2012 22:30:47  13991333          1  08/13/2012 22:36:42   13991333          2  08/13/2012 22:29:40 08/13/2012 22:31:14

What we are doing here is indexing groups of requests using dense_rank analytical function:

select t1.enc_id     , t1.contact     , to_date(t1.event_time, 'mm/dd/yyyy hh24:mi:ss') req     , dense_rank() over (partition by t1.enc_id, t1.contact order by to_date(t1.event_time, 'mm/dd/yyyy hh24:mi:ss')) gid     , to_date(t2.event_time, 'mm/dd/yyyy hh24:mi:ss') resp  From t1  left outer join t2    on (t1.enc_id = t2.enc_id   and        t1.contact = t2.contact) order by 1,2,3,5

Result:

  ENC_ID    CONTACT REQ                        GID RESP---------- ---------- ------------------- ---------- -------------------  13991333          1 08/13/2012 22:00:36          1 08/13/2012 22:25:40  13991333          1 08/13/2012 22:00:36          1 08/13/2012 22:29:31  13991333          1 08/13/2012 22:00:36          1 08/13/2012 22:30:47  13991333          1 08/13/2012 22:00:36          1 08/13/2012 22:31:35  13991333          1 08/13/2012 22:00:36          1 08/13/2012 22:31:49  13991333          1 08/13/2012 22:25:21          2 08/13/2012 22:25:40  13991333          1 08/13/2012 22:25:21          2 08/13/2012 22:29:31  13991333          1 08/13/2012 22:25:21          2 08/13/2012 22:30:47  13991333          1 08/13/2012 22:25:21          2 08/13/2012 22:31:35  13991333          1 08/13/2012 22:25:21          2 08/13/2012 22:31:49  13991333          1 08/13/2012 22:26:14          3 08/13/2012 22:25:40  13991333          1 08/13/2012 22:26:14          3 08/13/2012 22:29:31  13991333          1 08/13/2012 22:26:14          3 08/13/2012 22:30:47  13991333          1 08/13/2012 22:26:14          3 08/13/2012 22:31:35  13991333          1 08/13/2012 22:26:14          3 08/13/2012 22:31:49  13991333          1 08/13/2012 22:36:42          4 08/13/2012 22:25:40  13991333          1 08/13/2012 22:36:42          4 08/13/2012 22:29:31  13991333          1 08/13/2012 22:36:42          4 08/13/2012 22:30:47  13991333          1 08/13/2012 22:36:42          4 08/13/2012 22:31:35  13991333          1 08/13/2012 22:36:42          4 08/13/2012 22:31:49  13991333          2 08/13/2012 22:29:40          1 08/13/2012 22:31:14

And then picking nth value of response according to the index of group of requests. So, for the first group of requests it will be the first value of the response time in the group, for the second group of requests it will be the second value of the response time in the group and so forth.


Update (mimic behavior of nth_value analytical function for 10g)

SQL> with t1(ENC_ID, CONTACT, EVENT_TIME) as(  2    select 13991333,    1,   '08/13/2012 22:00:36' from dual union all  3    select 13991333,    1,   '08/13/2012 22:25:21' from dual union all  4    select 13991333,    1,   '08/13/2012 22:26:14' from dual union all  5    select 13991333,    1,   '08/13/2012 22:36:42' from dual union all  6    select 13991333,    2,   '08/13/2012 22:29:40' from dual  7  ),  8  t2(ENC_ID,CONTACT,EVENT_TIME) as(  9    select 13991333,    1,   '08/13/2012 22:25:40' from dual union all 10    select 13991333,    1,   '08/13/2012 22:29:31' from dual union all 11    select 13991333,    1,   '08/13/2012 22:30:47' from dual union all 12    select 13991333,    1,   '08/13/2012 22:31:35' from dual union all 13    select 13991333,    1,   '08/13/2012 22:31:49' from dual union all 14    select 13991333,    2,   '08/13/2012 22:31:14' from dual 15  ), 16  t3 as 17  ( 18  select z.* 19       , row_number() over (partition by enc_id, contact, req order by req) rn 20    from ( 21    select t1.enc_id 22         , t1.contact 23         , t1.event_time req 24         , dense_rank() over (partition by t1.enc_id, t1.contact order by t1.event_time) gid 25         , t2.event_time resp 26      from t1 27      left outer join t2 28        on (t1.enc_id = t2.enc_id   and 29            t1.contact = t2.contact) 30      order by 1,2,3,5 31    ) z 32  ) 33  select enc_id , contact, req, min(resp) resp 34    from ( 35           select q.enc_id 36                , q.contact 37                , q.req 38                , case 39                    when min(case rn when gid then resp end) over(partition by enc_id, contact, req order by req) > req 40                    then min(case rn when gid then resp end) over(partition by enc_id, contact, req order by req) 41                 end resp 42            from t3 q 43         ) 44  group by enc_id 45         , contact 46         , req 47  order by enc_id 48         , contact 49         , req 50  ;Result:    ENC_ID    CONTACT REQ                 RESP---------- ---------- ------------------- -------------------  13991333          1 08/13/2012 22:00:36 08/13/2012 22:25:40  13991333          1 08/13/2012 22:25:21 08/13/2012 22:29:31  13991333          1 08/13/2012 22:26:14 08/13/2012 22:30:47  13991333          1 08/13/2012 22:36:42   13991333          2 08/13/2012 22:29:40 08/13/2012 22:31:14


You are very close... try this:

SELECT  RQ.ENC_ID, RQ.CONTACT, RQ.EVENT_TIME REQ_EVENT_TIME,        min(RS.EVENT_TIME) RES_EVENT_TIMEFROM    RQLEFT OUTER JOIN RS ON RQ.ENC_ID=RS.ENC_ID  AND RQ.CONTACT=RS.CONTACT  AND RS.EVENT_TIME>RQ.EVENT_TIMEGROUP BY RQ.ENC_ID, RQ.CONTACT, RQ.EVENT_TIMEORDER BY 1,2,3,4