create table logins 
( Personid varchar2(10) 
, Login_time date 
) 
 
                        Table created.
insert into logins (Personid, Login_time) values (1, to_date('01012021 00:00', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
insert into logins (Personid, Login_time) values (1, to_date('01012021 01:00', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
insert into logins (Personid, Login_time) values (2, to_date('01012021 01:01', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
insert into logins (Personid, Login_time) values (2, to_date('01012021 01:30', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
insert into logins (Personid, Login_time) values (1, to_date('01012021 01:59', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
insert into logins (Personid, Login_time) values (1, to_date('01012021 02:00', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
insert into logins (Personid, Login_time) values (1, to_date('01012021 02:39', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
insert into logins (Personid, Login_time) values (1, to_date('01012021 03:00', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
insert into logins (Personid, Login_time) values (1, to_date('01012021 04:59', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
insert into logins (Personid, Login_time) values (2, to_date('01012021 02:00', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
insert into logins (Personid, Login_time) values (2, to_date('01012021 05:00', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
insert into logins (Personid, Login_time) values (2, to_date('01012021 06:00', 'DDMMYYYY HH24:MI'))
                        1 row(s) inserted.
with earliest_logins as  -- find earliest logins in a two hour block preceding each login record for the same person 
( select Personid 
  ,      login_time 
  ,      FIRST_VALUE(Login_time) IGNORE NULLS  
         OVER (PARTITION BY Personid ORDER BY login_time 
         RANGE BETWEEN INTERVAL '2' HOUR PRECEDING AND UNBOUNDED FOLLOWING) AS earliest_login 
  from   logins 
) 
, block_starters as -- retain rows that are the first login in a two hour block for a person 
( select personid 
  ,      login_time block_starttime 
  ,      login_time + INTERVAL '2' HOUR block_endtime 
  from   earliest_logins       
  where  login_time = earliest_login 
) 
, 
duplicate_logins as ( 
select l.personid 
,      l.login_time 
from block_starters bs 
JOIN 
logins l 
ON (l.personid = bs.personid and l.login_time between bs.block_starttime and bs.block_endtime) 
) 
select l.personid 
,      to_char(l.login_time, 'HH24:MI') login_time 
from   logins l 
       left outer join 
       duplicate_logins dl 
       on (l.personid = dl.personid and l.login_time = dl.login_time) 
where  dl.personid is null 
union 
select bs.personid 
,      to_char(bs.block_starttime, 'HH24:MI') login_time 
from   block_starters bs 
                        | PERSONID | LOGIN_TIME | 1 | 00:00 | 1 | 02:39 | 1 | 03:00 | 1 | 04:59 | 2 | 01:01 | 2 | 05:00 | 
|---|