Skip to content
Advertisement

Appending Name based on Min and Max datetime

I have Event_No, Events, Date Range in my table like below.

[Event_No, Events, Date Range
       1     PR    2/6/2018 12:01:00 AM
       1     PR    2/6/2018 12:02:00 AM
       1     PR    2/6/2018 12:03:00 AM
       1     RR    2/6/2018 12:04:00 AM
       1     RR    2/6/2018 12:05:00 AM
       1     RR    2/6/2018 12:06:00 AM
       1     SR    2/6/2018 12:07:00 AM
       1     SR    2/6/2018 12:08:00 AM
       1     SR    2/6/2018 12:09:00 AM
       2     PR    2/6/2018 01:01:00 AM
       2     PR    2/6/2018 01:02:00 AM
       2     PR    2/6/2018 01:03:00 AM
       2     RR    2/6/2018 01:04:00 AM
       2     RR    2/6/2018 01:05:00 AM
       2     RR    2/6/2018 01:06:00 AM
       2     SR    2/6/2018 01:07:00 AM
       2     SR    2/6/2018 01:08:00 AM
       2     SR    2/6/2018 01:09:00 AM

I need to show Min datetime respective Event name with ‘IN'(a concatenation of (Event-‘IN’))and Max datetime respective Event with Out(a concatenation of (Event-‘Out’)). I need My Final Output like below

Event_No   Events            Date Range      EventInOut
       1     PR    2/6/2018 12:01:00 AM       PR-IN
       1     PR    2/6/2018 12:03:00 AM       PR-OUT
       1     RR    2/6/2018 12:04:00 AM       RR-IN
       1     RR    2/6/2018 12:06:00 AM       RR-OUT
       1     SR    2/6/2018 12:07:00 AM       SR-IN
       1     SR    2/6/2018 12:09:00 AM       SR-OUT
       2     PR    2/6/2018 01:01:00 AM       PR-IN
       2     PR    2/6/2018 01:03:00 AM       PR-OUT
       2     RR    2/6/2018 01:04:00 AM       RR-IN 
       2     RR    2/6/2018 01:06:00 AM       RR-OUT
       2     SR    2/6/2018 01:07:00 AM       SR-IN
       2     SR    2/6/2018 01:09:00 AM       SR-OUT

Thanks

Advertisement

Answer

This is a gaps and islands problem.

select event_no, date,
       min(date), max(date)
from (select t.*,
             row_number() over (partition by event_no order by date) as seqnum,
             row_number() over (partition by event_no, event order by date) as seqnum_e
      from t
     ) t
group by event_no, event;

This puts the values on one row, which might meet your needs.

You can also use lead() and lag():

select t.*,
       (event || '-' || (case when prev_event is null then 'IN' else 'OUT' end))
from (select t.*,
             lag(event) over (partition by event_no order by date) as prev_event,
             lead(event) over (partition by event_no order by date) as next_event
      from t
     ) t
where prev_event is null or next_event is null;
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement