В Oracle 12.1 и выше проблемы с пропусками и островками, подобные этой, являются легкой задачей для предложения match_recognize
. Например:
Настройка таблицы
alter session set nls_timestamp_format = 'dd/mm/rr hh24:mi:ss,ff';
create table user_places (place, user_id, date_) as
select 'ABC', 4, to_timestamp('14/04/20 12:05:29,255000000') from dual union all
select 'ABC', 4, to_timestamp('14/04/20 15:42:28,389000000') from dual union all
select 'ABC', 4, to_timestamp('14/04/20 18:33:20,202000000') from dual union all
select 'ABC', 4, to_timestamp('14/04/20 22:51:28,339000000') from dual union all
select 'XYZ', 4, to_timestamp('14/04/20 11:07:23,335000000') from dual union all
select 'XYZ', 2, to_timestamp('14/04/20 12:15:12,123000000') from dual union all
select 'ABC', 4, to_timestamp('13/04/20 22:09:33,255000000') from dual union all
select 'QWE', 4, to_timestamp('13/04/20 10:18:29,144000000') from dual union all
select 'XYZ', 2, to_timestamp('14/04/20 10:05:47,255000000') from dual
;
commit;
Запрос и вывод
select place, user_id, date_
from (select * from user_places where user_id = 4)
match_recognize (
order by date_
all rows per match
pattern (a {- b* -} )
define b as place = a.place
)
order by date_ desc -- if needed
;
PLACE USER_ID DATE_
----- ------- ---------------------------
ABC 4 14/04/20 12:05:29,255000000
XYZ 4 14/04/20 11:07:23,335000000
ABC 4 13/04/20 22:09:33,255000000
QWE 4 13/04/20 10:18:29,144000000
Несколько вещей, на которые следует обратить внимание здесь :
DATE
является зарезервированным ключевым словом. Неверное имя столбца. Я использовал DATE_
вместо этого; обратите внимание на конечное подчеркивание. - Я жестко закодировал значение 4 . Конечно, лучшая практика состоит в том, чтобы превратить это в переменную связывания .
- Если вам действительно нужно сделать это только для одного
user_id
за один раз, это наиболее эффективно сделать что я сделал - сначала отфильтруйте строки в подзапросе. Однако, если вам нужно сделать это для всех идентификаторов пользователей в одном запросе, вам не нужен подзапрос; Вы выбираете из самой таблицы, и вам нужно добавить partition by user_id
в самом начале предложения match_recognize
, перед order by date_
.