Вот метод, который приближается к тому, что вы ожидаете.
С той разницей, что год не указан в названиях столбцов.
Таким образом, тот же запрос не нужно изменять в следующем году.
Как это работает?
Сначала даты начала и окончания месяцев генерируются в CTE.
Затем они объединяются в таблицу диапазонов.
Для расчета процента в месяц для каждого ресурса.
И этот результат затем поворачивается.
CREATE TABLE YourTable
(
Team_Name varchar2(30),
Res_Name varchar2(30),
Res_Start_Date date,
Res_End_Date date
);
INSERT INTO YourTable (Team_Name, Res_Name, Res_Start_Date, Res_End_Date)
SELECT 'Swoosh', 'Bob Jones', '1-JAN-2019', null FROM DUAL
UNION SELECT 'Swoosh', 'Mary Johnson', '5-MAY-2019', null FROM DUAL
UNION SELECT 'Marvel', 'Bill Bobberson', '29-OCT-2019', '31-DEC-2019' FROM DUAL
UNION SELECT 'Marvel', 'David James', '4-APR-2019', '28-APR-2019' FROM DUAL
UNION SELECT 'Marvel', 'John Smith', '1-MAY-2019', '1-OCT-2019' FROM DUAL
WITH MONTHS AS
(
SELECT
ADD_MONTHS(CAST('01-JAN-'||(EXTRACT(year FROM SYSDATE)-1) AS DATE), ROWNUM-1) AS month_start,
LAST_DAY(ADD_MONTHS(CAST('01-JAN-'||(EXTRACT(year FROM SYSDATE)-1) AS DATE), ROWNUM-1)) AS month_end
FROM DUAL
CONNECT BY ROWNUM <= 12
)
, PERCENTS AS
(
SELECT t.*
, EXTRACT(year from m.month_start) as "year"
, TO_CHAR(m.month_start,'MON') as "month"
, ROUND(100*((case when t.Res_End_Date < m.month_end then t.Res_End_Date else m.month_end end)
- (case when t.Res_Start_Date > m.month_start then t.Res_Start_Date else m.month_start end)
+ 1)/(m.month_end-m.month_start+1)) as perc
FROM MONTHS m
JOIN YourTable t
ON t.Res_Start_Date <= m.month_end
AND (t.Res_End_Date IS NULL OR t.Res_End_Date >= m.month_start)
)
SELECT *
FROM PERCENTS
PIVOT (SUM(perc) FOR "month" IN ('JAN' JAN,'FEB' FEB,'MAR' MAR,'APR' APR,'MAY' MAY,'JUN' JUN,'JUL' JUL,'AUG' AUG,'SEP' SEP,'OCT' OCT,'NOV' NOV,'DEC' DEC)) pvt
ORDER BY Team_Name DESC, Res_Name ASC
TEAM_NAME | RES_NAME | RES_START_DATE | RES_END_DATE | year | JAN | FEB | MAR | APR | MAY | JUN | JUL | AUG | SEP | OCT | NOV | DEC
:-------- | :------------- | :------------- | :----------- | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---:
Swoosh | Bob Jones | 01-JAN-19 | <em>null</em> | 2019 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100 | 100
Swoosh | Mary Johnson | 05-MAY-19 | <em>null</em> | 2019 | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | 87 | 100 | 100 | 100 | 100 | 100 | 100 | 100
Marvel | Bill Bobberson | 29-OCT-19 | 31-DEC-19 | 2019 | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | 10 | 100 | 100
Marvel | David James | 04-APR-19 | 28-APR-19 | 2019 | <em>null</em> | <em>null</em> | <em>null</em> | 83 | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em>
Marvel | John Smith | 01-MAY-19 | 01-OCT-19 | 2019 | <em>null</em> | <em>null</em> | <em>null</em> | <em>null</em> | 100 | 100 | 100 | 100 | 100 | 3 | <em>null</em> | <em>null</em>
дБ <> скрипка здесь