Здесь другое применение того же метода, что и в ответе MT0. Этот метод известен как метод «фиксированных различий» («фиксированные различия» в обоих решениях являются дополнительным вычисленным значением, по которому мы группируем данные);также известный как метод "tabibitosan".
В этом решении я вычитаю row_number()
(соответствующим образом измененный) непосредственно из даты, но после выбирая только строки с флагом, равным1. Это может быть важно, если у вас очень большой объем данных, но только относительно небольшая часть строк имеет флаг, равный 1. Это потому, что row_number()
необходимо упорядочить данных, изаказ дорогая операция. Чтобы решить эту проблему, нам не нужно упорядочивать (по дате) строки, где флаг равен 0 - только строки, где флаг равен 1.
EDIT (на основе MT0комментарий под этим ответом)
MT0 правильно указывает, что мое решение предполагает что-то верное в тестовых данных, опубликованных ОП, но не указано явно. А именно, что время-дата в столбце date_measured
- это непрерывные последовательности даты-времени с интервалом в один час.
На самом деле, мое решение действительно заключается в следующем. Предположим, что с самого начала данные состояли только из строк вне диапазона (с флагом, равным 1), и что время-дата в столбце date_measured
всегда округлялось до часа, как и вДанные испытаний ОП. Таким образом, вопрос состоит в том, чтобы идентифицировать последовательности строк, в которых времена являются «последовательными» (то есть с интервалом в один час). Вот что делает запрос.
END EDIT
Я использовал таблицу MT0 - из его теста db fiddle. Спасибо MT0!
with
tabibitosan (id, date_measured, grp) as (
select id, date_measured,
date_measured
- row_number() over (partition by id order by date_measured)
* interval '1' hour
from table_name
where out_of_range = 1
)
select id, min(date_measured) as date_measured_start,
max(date_measured) as date_measured_end,
count(*) as consecutive_out_of_range
from tabibitosan
group by id, grp
order by id, date_measured_start -- or whatever
;
ID DATE_MEASURED_START DATE_MEASURED_END CONSECUTIVE_OUT_OF_RANGE
---- ------------------- ----------------- ------------------------
3125 2019-08-09 21:00 2019-08-09 22:00 2
3125 2019-08-10 00:00 2019-08-10 02:00 3
3147 2019-08-09 20:00 2019-08-09 20:00 1
3147 2019-08-09 23:00 2019-08-10 01:00 3