Я столкнулся с проблемой. Я не могу понять, как объединить последовательные строки диапазона дат вместе на основе двух измерений. Один мне подходит, но второй доставляет неприятности
Представим себе таблицу в этой структуре с четырьмя возможными сценариями.
emp_id | level | date_from | date_to
--------------------------------------------------
1 | A | 7/31/2015 | 3/31/2016
1 | A | 4/1/2016 | 1/1/3000
2 | A | 7/31/2015 | 1/1/3000
3 | A | 5/31/2015 | 12/31/2015
3 | B | 1/1/2016 | 3/31/2016
3 | A | 4/1/2016 | 6/30/2016
3 | B | 7/1/2016 | 1/1/3000
4 | A | 5/31/2015 | 12/31/2015
4 | A | 1/1/2016 | 6/30/2016
4 | B | 7/1/2016 | 1/1/3000
Я хочу объединить только те строки, которые имеют последовательные диапазоны дат и act_level = prev_level
Я пытался сделать что-то подобное
SELECT emp_id
, level
, date_from
, date_to
--
, CASE
WHEN lag(level) over (partition by emp_id order by date_from) = level THEN
CASE
WHEN lag(date_to) over (partition by emp_id, level order by date_from) = date_from-1
THEN lag(date_from) over (partition by code_employee, level_name order by date_from)
ELSE NULL
END
ELSE
CASE
WHEN lag(level) over (partition by emp_id order by date_from) = level
OR
lead(level) over (partition by emp_id order by date_from) = level
THEN NULL
ELSE date_from
END
END date_from_new
, date_to as date_to_new
--
FROM src_table
--
WHERE 1=1
это дает мне почти те результаты, которые я хочу:
emp_id | level | date_from | date_to | d_from_new | d_from_to
--------------------------------------------------------------------------
1 | A | 7/31/2015 | 3/31/2016 | | 3/31/2016
1 | A | 4/1/2016 | 1/1/3000 | 7/31/2015 | 1/1/3000
2 | A | 7/31/2015 | 1/1/3000 | 7/31/2015 | 1/1/3000
3 | A | 5/31/2015 | 12/31/2015 | 5/31/2015 | 12/31/2015
3 | B | 1/1/2016 | 3/31/2016 | 1/1/2016 | 3/31/2016
3 | A | 4/1/2016 | 6/30/2016 | 4/1/2016 | 6/30/2016
3 | B | 7/1/2016 | 1/1/3000 | 7/1/2016 | 1/1/3000
4 | A | 5/31/2015 | 12/31/2015 | | 12/31/2015
4 | A | 1/1/2016 | 6/30/2016 | 5/31/2015 | 6/30/2016
4 | B | 7/1/2016 | 1/1/3000 | 7/1/2016 | 1/1/3000
Я просто отфильтрую результат для d_from_new (date_from_new) не нулевых значений. Но я не уверен, что произойдет, если будет, например, в 3 раза тот же уровень с последовательным диапазоном дат или в 8 раз.
И, честно говоря, мне этот запрос не нравится :)
Есть ли у вас какое-нибудь решение, "благоприятное для парфюмерии" и "приятное для глаз"?
act_level = prev_level
, но взгляните на Интервалы упаковки Автор: Ицик Бен-Ган. Он написан для SQL Server, но Oracle поддерживает все используемые там аналитические функции. - person Vladimir Baranov   schedule 04.10.2016