Был бы очень признателен за помощь в попытке сгруппировать перекрывающиеся периоды. Это исходные данные, которые у меня есть в таблице 1:
Start_Date End_Date Status Id Main_Id
01.01.2020 03.05.2020 0 11 1
01.02.2020 14.04.2020 3 12 1
14.04.2020 15.05.2020 5 13 1
10.05.2020 20.05.2020 0 14 1
22.05.2020 25.05.2020 2 15 1
Желаемый результат:
Valid_Period Decision Main_Id
01.01.2020 01.02.2020 NOK 1
01.02.2020 03.05.2020 DOOMED 1
03.05.2020 10.05.2020 BAD 1
10.05.2020 15.05.2020 DOOMED 1
15.05.2020 20.05.2020 NOK 1
20.05.2020 22.05.2020 OK 1
22.05.2020 25.05.2020 BAD 1
В выходных данных может быть 4 разных решения, основанных на входном статусе и периоде:
- Статус 0 существует (и одновременно нет статуса ›0) - 'NOK'
- Статус ›0 существует (но в то же время нет статуса 0) - «ПЛОХО»
- Статус ›0 и 0 существуют вместе - 'ОБРЕЧЕН'
- Ни один из других статусов не существует - он предназначен для покрытия временных промежутков между периодами - «ОК».
Вывод, который я позже буду использовать для целей отчетности, должен иметь возможность получить правильный результат для каждого Main_Id в любой момент времени. До сих пор я пытался с помощью одного SELECT сгруппировать перекрывающиеся статусы 0 и ›0 и с помощью отдельного SELECT, чтобы покрыть временные промежутки, а затем UNIION ALL, чтобы собрать все вместе:
select NORMALIZE ON MEETS OR OVERLAPS (
case
when table1.Status = 1 then 'NOK'
when table1.Status >1 then 'BAD' end) Decision,
period(table1.Start_Date, coalesce (table1.End_Date, cast('9999-01-01' as date))) valid_period,
table1.Main_Id
from table1
union all
select 'OK' Decision,
period (a.prev_end_date, a.Start_Date) valid_period,
a.Main_Id
from (
select
table1.Main_Id,
LAG (table1.End_Date) over (
partition by table1.Main_Id
order by table1.Start_Date, coalesce (table1.End_Date, cast('9999-01-01' as date))) prev_end_date,
table1.Start_Date
from table1
qualify prev_end_date < table1.Start_Date)a
;
Текущий вывод должен быть примерно таким:
01.01.2020 03.05.2020 NOK
01.02.2020 15.05.2020 BAD
10.05.2020 20.05.2020 NOK
22.05.2020 25.05.2020 BAD
20.05.2020 22.0.2020 OK
Это первый раз, когда я пытаюсь использовать тип данных Teradata PERIOD, поэтому все еще учусь. Также пытался с calendar_date получить одну строку для каждого дня в периоде, но он не покрывает пробелы, и катушка уже становится слишком большой:
select c.calendar_date,table1
MAX(CASE
WHEN table1.status = 1
THEN 1
ELSE 0
END) NOK,
MAX(CASE
WHEN table1.status > 1
THEN 1
ELSE 0
END) BAD
from table1
join table_calendar c
on table1.start_date<=c.calendar_date and (
table1.end_date>c.calendar_date or c.calendar_date is null
)
group by c.calendar_date
;
Поэтому все еще изо всех сил пытаюсь получить желаемый результат с хорошей производительностью. Любая помощь будет оценена по достоинству. Заранее спасибо!