I have a sequence in my Oracle database for example:
|Event code | Event time |
|41164 | jan-20-2016 |
|41165 | jan-21-2016 |
|41164 | jan-27-2016 |
|41164 | jan-30-2016 |
|41164 | jan-31-2016 |
|41165 | Feb-01-2016 |
|41164 | Feb-03-2016 |
|41164 | Feb-05-2016 |
|41165 | Feb-01-2016 |
I need to return every occurrence of 41164 directly before the next 41165.
How would I do this with a query?
Oracle Setup :
CREATE TABLE Events (Event_code, Event_time ) AS
SELECT 41164, DATE '2016-01-20' FROM DUAL UNION ALL
SELECT 41165, DATE '2016-01-21' FROM DUAL UNION ALL
SELECT 41164, DATE '2016-01-27' FROM DUAL UNION ALL
SELECT 41164, DATE '2016-01-30' FROM DUAL UNION ALL
SELECT 41164, DATE '2016-01-31' FROM DUAL UNION ALL
SELECT 41165, DATE '2016-02-01' FROM DUAL UNION ALL
SELECT 41164, DATE '2016-02-03' FROM DUAL UNION ALL
SELECT 41164, DATE '2016-02-05' FROM DUAL UNION ALL
SELECT 41165, DATE '2016-02-01' FROM DUAL;
Query - Ordered by fetch order :
SELECT Event_Code,
Event_Time
FROM (
SELECT e.*,
LEAD( Event_Code ) OVER ( ORDER BY ROWID ) as next_code
FROM Events e
)
WHERE Event_Code = 41164
AND Next_Code = 41165;
Output :
EVENT_CODE EVENT_TIME
---------- -------------------
41164 2016-01-20 00:00:00
41164 2016-01-31 00:00:00
41164 2016-02-05 00:00:00
Query - Ordered by date order :
SELECT Event_Code,
Event_Time
FROM (
SELECT e.*,
LEAD( Event_Code ) OVER ( ORDER BY Event_Time ) as next_code
FROM Events e
)
WHERE Event_Code = 41164
AND Next_Code = 41165;
Output :
EVENT_CODE EVENT_TIME
---------- -------------------
41164 2016-01-20 00:00:00
41164 2016-01-31 00:00:00
As indicated, requirement is not clear (For example, what should happen if more than these 2 numbers are available? If on next date you have both numbers, how you need to treat it ? etc )
You can start with and adapt below SQL:
select event_code from (
select
event_code,
lead(event_code) over ( order by event_time ) next_event_code
from events )
where event_code < next_event_code;
NOTE: Written from memory, not tested
This has been tested on oracle DB, you can run it without the DB and check if that is what you are looking for. Used lead analytical function to get the result.
with seq as
(select
41164 a, 'jan-20-2016' b
from dual
union
select
41165 a, 'jan-21-2016' b
from dual
union
select
41164 a, 'jan-27-2016' b
from dual
union
select
41164 a, 'jan-30-2016' b
from dual
union
select
41164 a, 'jan-31-2016' b
from dual
union
select
41165 a, 'Feb-01-2016' b
from dual),
rown as
(select
a, to_date(b,'mon-dd-yyyy') d, b
from seq),
lead as
(select
a, lead(a) over (order by d) c, b from rown)
select
a, c, b
from lead
where
a = 41164 and
c=41165 ;
returns
41164 41165 jan-20-2016
41164 41165 jan-31-2016
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.