Предполагая, что вы группируете последовательный флаг = 1 ряд, вы можете сделать это, используя комбинацию техники Tabibitosan и dens_rank, например:
WITH tmp AS (select 'username1' as username, to_date('2019-04-01 00:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag from dual union all
select 'username1' as username, to_date('2019-04-01 01:00','YYYY-MM-DD HH24:MI') as startdate, 0 as flag from dual union all
select 'username1' as username, to_date('2019-04-01 02:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag from dual union all
select 'username1' as username, to_date('2019-04-01 03:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag from dual union all
select 'username1' as username, to_date('2019-04-01 04:00','YYYY-MM-DD HH24:MI') as startdate, 0 as flag from dual union all
select 'username1' as username, to_date('2019-04-02 05:00','YYYY-MM-DD HH24:MI') as startdate, 0 as flag from dual union all
select 'username1' as username, to_date('2019-04-02 01:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag from dual union all
select 'username1' as username, to_date('2019-04-02 02:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag from dual union all
select 'username1' as username, to_date('2019-04-02 03:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag from dual union all
select 'username1' as username, to_date('2019-04-02 04:00','YYYY-MM-DD HH24:MI') as startdate, 0 as flag from dual),
tabibitosan AS (SELECT tmp.*,
CASE
WHEN flag = 1 THEN
row_number() over(ORDER BY startdate) - row_number() over(PARTITION BY flag ORDER BY startdate)
END grp
FROM tmp)
SELECT username,
startdate,
flag,
CASE
WHEN flag = 1 THEN
dense_rank() over(PARTITION BY flag ORDER BY grp)
END rnk
FROM tabibitosan
ORDER BY startdate,
username;
USERNAME STARTDATE FLAG RNK
--------- ------------------- ---------- ----------
username1 01/04/2019 00:00:00 1 1
username1 01/04/2019 01:00:00 0
username1 01/04/2019 02:00:00 1 2
username1 01/04/2019 03:00:00 1 2
username1 01/04/2019 04:00:00 0
username1 02/04/2019 01:00:00 1 3
username1 02/04/2019 02:00:00 1 3
username1 02/04/2019 03:00:00 1 3
username1 02/04/2019 04:00:00 0
username1 02/04/2019 05:00:00 0
Я обновил запрос, чтобы учесть дополнительный столбец порогового значения:
WITH tmp AS (select 'username1' as username, to_date('2019-04-01 00:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag, 1 as threshold from dual union all
select 'username1' as username, to_date('2019-04-01 01:00','YYYY-MM-DD HH24:MI') as startdate, 0 as flag, null as threshold from dual union all
select 'username1' as username, to_date('2019-04-01 02:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag, 1 as threshold from dual union all
select 'username1' as username, to_date('2019-04-01 03:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag, null as threshold from dual union all
select 'username1' as username, to_date('2019-04-01 04:00','YYYY-MM-DD HH24:MI') as startdate, 0 as flag, null as threshold from dual union all
select 'username1' as username, to_date('2019-04-01 05:00','YYYY-MM-DD HH24:MI') as startdate, 0 as flag, null as threshold from dual union all
select 'username1' as username, to_date('2019-04-02 01:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag, null as threshold from dual union all
select 'username1' as username, to_date('2019-04-02 02:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag, 1 as threshold from dual union all
select 'username1' as username, to_date('2019-04-02 03:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag, 1 as threshold from dual union all
select 'username1' as username, to_date('2019-04-02 04:00','YYYY-MM-DD HH24:MI') as startdate, 1 as flag, null as threshold from dual union all
select 'username1' as username, to_date('2019-04-02 05:00','YYYY-MM-DD HH24:MI') as startdate, 0 as flag, null as threshold from dual),
tabibitosan AS (SELECT tmp.*,
CASE
WHEN flag = 1 THEN
row_number() over(PARTITION BY username ORDER BY startdate) - row_number() over(PARTITION BY username, flag ORDER BY startdate)
END grp,
SUM(CASE WHEN flag = 1 THEN threshold END) OVER (PARTITION BY username, flag ORDER BY startdate) threshold_sum -- assumes threshold is 1 or null; change the case statement inside the sum if this isn't the case
FROM tmp)
SELECT username,
startdate,
flag,
threshold,
CASE
WHEN flag = 1 THEN
dense_rank() over(PARTITION BY flag ORDER BY grp, threshold_sum)
END rnk
FROM tabibitosan
ORDER BY startdate,
username;
USERNAME STARTDATE FLAG THRESHOLD RNK
--------- ----------- ---------- ---------- ----------
username1 01/04/2019 1 1 1
username1 01/04/2019 0
username1 01/04/2019 1 1 2
username1 01/04/2019 1 2
username1 01/04/2019 0
username1 01/04/2019 0
username1 02/04/2019 1 3
username1 02/04/2019 1 1 4
username1 02/04/2019 1 1 5
username1 02/04/2019 1 5
username1 02/04/2019 0
Обратите внимание, что столбец порогового значения может быть только 1 или нулевым;если это не так, вам придется обновить условную сумму в соответствии с вашими данными.
Я также обновил разделение аналитических функций, включив в него столбец имени пользователя, поскольку я предполагаю, что этопервичный ключ для данных.
Наконец, обратите внимание, что я немного изменил ваши выборочные данные, чтобы показать, что если порог равен нулю для первой строки в группе с флагом = 1, он будет сам по себегруппа, если в следующей строке установлен порог.Если это не то поведение, которое вы желаете, вам нужно обновить свой вопрос с помощью логики, которую вы желаете.