Это проблема пробелов и островков.
Вы можете использовать lag()
для извлечения предыдущего rate
для того же кортежа валют, а затем выполнить суммирование окна, чтобы определить группы последовательных записей с помощью та же скорость. Затем вы можете объединить группы и восстановить предыдущий показатель, снова используя lag()
. Последний шаг - фильтрация по группам, имеющим не менее 3 записей.
select *
from (
select
from_cur,
to_cur,
rate,
max(date) max_date,
lag(rate) over(partition by from_cur, to_cur order by max(date)) lag_rate_grp,
count(*) cnt
from (
select
t.*,
sum(case when rate = lag_rate then 0 else 1 end) over(partition by from_date, to_date order by date) grp
from (
select
t.*,
lag(rate) over(partition by from_cur, to_cur order by date) lag_rate
from mytable t
) t
) t
group by from_cur, to_cur, rate, grp
) t
where cnt >= 3
order by from_cur, to_cur, max_date
На самом деле, использование разницы между номерами строк может сохранить один уровень вложенности:
select *
from (
select
from_cur,
to_cur,
rate,
max(date) max_date,
lag(rate) over(partition by from_cur, to_cur order by max(date)) lag_rate_grp,
count(*) cnt
from (
select
t.*,
row_number() over(partition by from_cur, to_cur order by date) rn1,
row_number() over(partition by from_cur, to_cur, rate order by date) rn2
from mytable t
) t
group by from_cur, to_cur, rate, rn1 - rn2
) t
where cnt >= 3
order by from_cur, to_cur, max_date
Если вы хотите, чтобы в кортеже валюты была только самая ранняя запись, вы можете использовать row_number()
:
select *
from (
select
from_cur,
to_cur,
rate,
max(date) max_date,
lag(rate) over(partition by from_cur, to_cur order by max(date)) lag_rate_grp,
count(*) cnt,
row_number() over(partition by from_cur, to_cur, case when count(*) >= 3 then 0 else 1 end order by max(date)) rn
from (
select
t.*,
row_number() over(partition by from_cur, to_cur order by date) rn1,
row_number() over(partition by from_cur, to_cur, rate order by date) rn2
from mytable t
) t
group by from_cur, to_cur, rate, rn1 - rn2
) t
where cnt >= 3 and rn = 1
order by from_cur, to_cur