Я записываю решение только для этого одного случая. Как страхователь уже сказал вам, вы должны предоставить другие кейсы, если таковые имеются, и показать нам, что вы пробовали раньше. Скорее всего, это превратится в ад CASE WHEN
, но я надеюсь, что приведенное ниже решение даст вам некоторое представление.
Решение
WITH MAIN
AS (SELECT TO_DATE ('01012020', 'DDMMYYYY') AS Start_DATE,
TO_DATE ('31012020', 'DDMMYYYY') AS End_Date,
'S' AS config
FROM DUAL
UNION ALL
SELECT TO_DATE ('15012020', 'DDMMYYYY') AS Start_DATE,
TO_DATE ('20012020', 'DDMMYYYY') AS End_Date,
'D' AS config
FROM DUAL
UNION ALL
SELECT TO_DATE ('15022020', 'DDMMYYYY') AS Start_DATE,
TO_DATE ('20022020', 'DDMMYYYY') AS End_Date,
'D' AS config
FROM DUAL
UNION ALL
SELECT TO_DATE ('01032020', 'DDMMYYYY') AS Start_DATE,
TO_DATE ('20032020', 'DDMMYYYY') AS End_Date,
'S' AS config
FROM DUAL
),
MAIN2
AS (SELECT START_DATE AS DET FROM MAIN
UNION
SELECT END_DATE FROM MAIN),
MAIN3
AS (SELECT DET AS START_DATE,
LEAD (DET, 1)
OVER (PARTITION BY TO_CHAR (DET, 'YYYYMM') ORDER BY DET)
AS END_DATE,
LEAD (DET, 1)
OVER (PARTITION BY TO_CHAR (DET, 'YYYYMM') ORDER BY DET)
- 1
ED2,
LEAD (DET, 1)
OVER (PARTITION BY TO_CHAR (DET, 'YYYYMM') ORDER BY DET)
+ 1
ED3
FROM MAIN2),
MAIN4
AS (SELECT *
FROM MAIN3
WHERE END_DATE IS NOT NULL),
MAIN5
AS (SELECT CASE
WHEN B.START_DATE IS NOT NULL
THEN
B.START_DATE
WHEN B.START_DATE IS NULL
AND LAG (
A.START_DATE,
1)
OVER (
PARTITION BY TO_CHAR (A.START_DATE, 'YYYYMM')
ORDER BY A.START_DATE)
IS NOT NULL
THEN
LAG (
A.START_DATE,
1)
OVER (PARTITION BY TO_CHAR (A.START_DATE, 'YYYYMM')
ORDER BY A.START_DATE)
+ 1
WHEN B.START_DATE IS NULL
AND LAG (
A.START_DATE,
1)
OVER (
PARTITION BY TO_CHAR (A.START_DATE, 'YYYYMM')
ORDER BY A.START_DATE)
IS NULL
THEN
A.START_DATE
END
START_DATE,
CASE
WHEN B.END_DATE IS NOT NULL
THEN
B.END_DATE
WHEN B.END_DATE IS NULL
AND LEAD (
A.END_DATE,
1)
OVER (PARTITION BY TO_CHAR (A.END_DATE, 'YYYYMM')
ORDER BY A.START_DATE)
IS NOT NULL
THEN
A.END_DATE - 1
WHEN B.END_DATE IS NULL
AND LEAD (
A.END_DATE,
1)
OVER (PARTITION BY TO_CHAR (A.END_DATE, 'YYYYMM')
ORDER BY A.START_DATE)
IS NULL
THEN
A.END_DATE
END
END_DATE,
B.START_DATE ST,
B.END_DATE ED,
CASE WHEN B.CONFIG IS NOT NULL THEN B.CONFIG ELSE 'S' END
CONFIG
FROM MAIN4 A
LEFT JOIN MAIN B
ON B.START_DATE = A.START_DATE AND B.END_DATE = A.END_DATE --AND B.CONFIG='D'
)
SELECT START_DATE, END_DATE, CONFIG
FROM MAIN5
ORDER BY 1
введите описание изображения здесь