Проблема усложняется требованием «маскировать» значение - 0 становится равным 1 при некоторых условиях. В противном случае это было бы прямым применением метода табибитозана. Более того, в конечном выводе вы хотите исходные значения, а не маскированные, поэтому мы должны быть осторожны с тем, что мы сохраняем и что отбрасываем на каждом шаге.
Вот один из способов решения проблемы. Обратите внимание, что DATE
является ключевым словом Oracle, поэтому его не следует использовать в качестве имени столбца (он может не вызывать синтаксическую ошибку, но затрудняет понимание кода). Я не проверял, является ли VALUE
также ключевым словом; просто для безопасности я изменил имена обоих столбцов на DT
и VAL
. (Как вы увидите, в моем коде я создаю столбцы GRP
и CT
для группы и количества соответственно; GROUP
и COUNT
являются ключевыми словами Oracle, поэтому применимо то же самое.)
with
inputs(region, dt, val) as (
select 'East', to_date('1/1/2018' , 'mm/dd/yyyy'), 1 from dual union all
select 'East', to_date('1/2/2018' , 'mm/dd/yyyy'), 1 from dual union all
select 'East', to_date('1/3/2018' , 'mm/dd/yyyy'), 0 from dual union all
select 'East', to_date('1/4/2018' , 'mm/dd/yyyy'), 1 from dual union all
select 'East', to_date('1/6/2018' , 'mm/dd/yyyy'), 1 from dual union all
select 'East', to_date('1/7/2018' , 'mm/dd/yyyy'), 0 from dual union all
select 'West', to_date('1/9/2018' , 'mm/dd/yyyy'), 0 from dual union all
select 'West', to_date('1/10/2018', 'mm/dd/yyyy'), 0 from dual union all
select 'West', to_date('2/3/2018' , 'mm/dd/yyyy'), 1 from dual union all
select 'West', to_date('2/4/2018' , 'mm/dd/yyyy'), 1 from dual union all
select 'West', to_date('2/5/2018' , 'mm/dd/yyyy'), 1 from dual union all
select 'West', to_date('2/8/2018' , 'mm/dd/yyyy'), 0 from dual union all
select 'West', to_date('2/9/2018' , 'mm/dd/yyyy'), 0 from dual union all
select 'West', to_date('2/10/2018', 'mm/dd/yyyy'), 0 from dual union all
select 'West', to_date('2/11/2018', 'mm/dd/yyyy'), 1 from dual union all
select 'West', to_date('2/12/2018', 'mm/dd/yyyy'), 0 from dual union all
select 'West', to_date('2/13/2018', 'mm/dd/yyyy'), 1 from dual union all
select 'West', to_date('2/14/2018', 'mm/dd/yyyy'), 1 from dual union all
select 'West', to_date('2/17/2018', 'mm/dd/yyyy'), 0 from dual union all
select 'West', to_date('2/18/2018', 'mm/dd/yyyy'), 0 from dual union all
select 'West', to_date('2/19/2018', 'mm/dd/yyyy'), 1 from dual union all
select 'West', to_date('2/20/2018', 'mm/dd/yyyy'), 0 from dual union all
select 'West', to_date('2/21/2018', 'mm/dd/yyyy'), 1 from dual union all
select 'West', to_date('2/22/2018', 'mm/dd/yyyy'), 0 from dual union all
select 'West', to_date('2/23/2018', 'mm/dd/yyyy'), 1 from dual
)
, prep(region, dt, val, adj_val) as (
select region, dt, val,
case when val = 1
or lag(val) over (partition by region order by dt) = 1
and
lead(val) over (partition by region order by dt) = 1
then 1 else 0 end
from inputs
)
, tabibitosan(region, dt, val, adj_val, grp) as (
select region, dt, val, adj_val,
row_number() over (partition by region order by dt)
- row_number() over (partition by region, adj_val order by dt)
from prep
)
, group_counts(region, dt, val, ct) as (
select region, dt, val, count(*) over (partition by region, grp)
from tabibitosan
where adj_val = 1
)
select region, dt, val
from group_counts
where ct >= 3
order by region, dt
;
Выход:
REGION DT VAL
------ --------- ----------
East 01-Jan-18 1
East 02-Jan-18 1
East 03-Jan-18 0
East 04-Jan-18 1
East 06-Jan-18 1
West 03-Feb-18 1
West 04-Feb-18 1
West 05-Feb-18 1
West 11-Feb-18 1
West 12-Feb-18 0
West 13-Feb-18 1
West 14-Feb-18 1
West 19-Feb-18 1
West 20-Feb-18 0
West 21-Feb-18 1
West 22-Feb-18 0
West 23-Feb-18 1