简体   繁体   中英

How do I find the last occurrence of a given sequence of numbers repetitively?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM