如果没有月份的数据,则按月返回明智的计数,作为Oracle SQL中的计数返回0

时间:2019-03-08 09:48:17

标签: sql oracle

我有一个表格,其中包含一月到三月的数据(到当前月份),我可以进行月份的计数。但是用户需要在该月的其余时间显示零。建议。

例如:

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')

输出:

cnt    Process_month

20     JANUARY

35     FEBUARY

26     March

所需的输出:

cnt    Process_month

20     JANUARY

35     FEBUARY

26     March

0      APRIL

0      MAY
…….
….
….
0      DECEMBER

请协助。

3 个答案:

答案 0 :(得分:1)

使用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')

答案 1 :(得分:0)

这是一个普遍的问题,实际上不是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;

答案 2 :(得分:0)

months生成器与您的查询正确连接

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

Months Generator是一个简单的分层查询,可为我们提供12个值0102 ... 12

select to_char(level, 'fm00') mth_num from dual connect by level <= 12

您还可以使用系统视图获取这些数字:

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