select login_date
,id
,flag
,case when flag = 'Y' then min(login_date) over(partition by id,grp) end as flag_date
from (select login_date,id,flag
,row_number() over(partition by id order by login_date) -
row_number() over(partition by id,flag order by login_date) as grp
from tbl
) t
- Сначала классифицируйте строки по группам, то есть последовательно 'Y' и 'N начинают новое значение, когда серия разрывается. Это можно сделать с помощью подхода с разницей номеров строк. ( Запустите внутренний запрос, чтобы увидеть, как присваиваются номера групп )
- Как только группы назначены, вычислять flag_date с условным агрегированием тривиально.
Еще один подход для решения этой проблемы заключается в создании новой группы всякий раз, когда встречается значение 'N'. Внешний запрос остается прежним, меняется только внутренний.
select login_date
,id
,flag
,case when flag = 'Y' then min(login_date) over(partition by id,grp) end as flag_date
from (select login_date,id,flag
,sum(case when flag = 'N' then 1 else 0 end) over(partition by id order by login_date) as grp
from tbl
) t