Вам нужно использовать список коллекций. Вы не можете изменять размер массива.
Присоединитесь к генератору месяцев по вашему запросу:
select to_char(to_date(mth_num, 'MM'), 'MONTH') month, nvl(cnt, 0) cnt
from (
select count(emp_id) as cnt, to_char(due_date, 'mm') mth_num
from emp_request where due_date is not null
group by to_char(due_date, 'mm')) e
right join (
select to_char(level, 'fm00') mth_num
from dual connect by level <= 12) m using (mth_num)
order by mth_num
dbfiddle demo sup>
Генератор месяцев - это простой иерархический запрос, который дает нам 12 значений 01
, 02
... 12
:
select to_char(level, 'fm00') mth_num from dual connect by level <= 12
Вы также можете использовать системные представления для получения этих чисел: [ 1114]
select to_char(rownum, 'fm00') mth_num from all_objects where rownum <= 12
или этот синтаксис:
select to_char(column_value, 'fm00') mth_num
from table(sys.odcivarchar2list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))
Лучше работать с числами, которые можно правильно отсортировать и преобразовать в названия месяцев на последнем шаге. Таким образом, у вас есть естественный месячный порядок. Если вы хотите быть уверены, что названия месяцев всегда на английском языке, не зависят от локальных настроек, используйте to_date
с третьим параметром, как здесь:
select to_char(sysdate, 'month', 'nls_date_language=english') from dual
используйте WWV_FLOW_MONTHS_MONTH, чтобы получить весь месяц, и оставьте соединение с вашим запросом, чтобы получить название месяца из столбца даты и присоединиться к нему
with cte
(
SELECT month_display as month FROM WWV_FLOW_MONTHS_MONTH
) , cnt as
(
select count(a.emp_id) as cnt ,
to_char(a.due_date,'MONTH') as Process_Month from EMP_Request a
where a.due_date is not null
group by to_char(a.due_date,'MONTH')
) select coalesce(Process_Month,month), cnt from cte left join cnt on cte.month=cnt.to_char(to_date(Process_Month, 'DD-MM-YYYY'), 'Month')
Это общая проблема, которая на самом деле не является проблемой sql. SQL на самом деле не знает, какие месяцы вас интересуют. Поэтому решение заключается в том, чтобы указать это в подзапросе.
Вот решение, которое не использует внешние таблицы. Вы просто выбираете все месяцы года, а внешние присоединяются к вашим данным.
select TO_CHAR(TO_DATE(available_months.m,'MM'),'MONTH') , NVL(sum(data.cnt),0) from
(select to_number(to_char(sysdate,'MM')) m, 7 cnt from dual) data,
(select 1 m from dual union select 2 from dual union select 3 from dual union select 4 from dual
union select 5 from dual union select 6 from dual union select 7 from dual
union select 8 from dual union select 9 from dual union select 10 from dual
union select 11 from dual union select 12 from dual) available_months
where
data.m (+) = available_months.m
group by available_months.m
order by available_months.m;
Или с включенным запросом данных это должно выглядеть (не проверено):
select TO_CHAR(TO_DATE(available_months.m,'MM'),'MONTH') , NVL(sum(data.cnt),0) from
(select count(a.emp_id) as cnt ,to_char(a.due_date,'MONTH') as Process_Month from EMP_Request a where a.due_date is not null) data
(select 1 m from dual union select 2 from dual union select 3 from dual union select 4 from dual
union select 5 from dual union select 6 from dual union select 7 from dual
union select 8 from dual union select 9 from dual union select 10 from dual
union select 11 from dual union select 12 from dual) available_months
where
data.due_date (+) = available_months.m
group by available_months.m
order by available_months.m;