从Oracle检索0计数的行

时间:2016-07-14 07:38:18

标签: oracle

我正在查询一个查询,该查询可以按月回收将于今年夏天关闭的办公室的数量。

SELECT
    qa.tmonth,
    COUNT(qa.tmonth) AS qtn
FROM
(
    SELECT TO_CHAR(CLOSURE_DATE, 'yyyymm') AS tmonth
    FROM Holidays
    WHERE CLOSURE_DATE >= TO_DATE('20160501', 'YYYY-MM-DD') AND
          CLOSURE_DATE <= TO_DATE('20160901', 'YYYY-MM-DD')
) qa
GROUP BY qa.tmonth;

由于月份:5月,6月,8月和9月没有办公室将关闭,产出如下:

TMONTH|QTN
201607|80

但我需要这样的事情

TMONTH|QTN
201605|0
201606|0
201607|80
201608|0
201609|0

我怎么能实现这个目标?

感谢所有人!

2 个答案:

答案 0 :(得分:0)

你可以尝试这样的事情:

SQL> with holidays(closure_date) as
  2  (
  3    select date '2016-07-01' from dual union all
  4    select date '2016-07-02' from dual union all
  5    select date '2016-07-03' from dual union all
  6    select date '2016-07-04' from dual union all
  7    select date '2016-07-05' from dual
  8  )
  9  select count(closure_date) as closure_days, to_char(day, 'yyyymm') as month
 10  from (
 11          select date '2016-05-01' + level -1 as day
 12          from dual
 13          connect by date '2016-05-01' + level -1 <= date '2016-09-30'
 14       ) days
 15       left outer join holidays
 16         on (day = closure_date)
 17  group by to_char(day, 'yyyymm') ;

CLOSURE_DAYS MONTH
------------ ------
           0 201608
           5 201607
           0 201606
           0 201605
           0 201609

SQL>

这使用查询来构建开始日期和结束日期之间的所有日期的列表;我使用01/05和30/09并将其称为days

然后使用外连接中的days表查询holidays;通过这种方式,您只能计算关闭日期列表中存在相应值的日期,从而计算每天,每年的关闭日期;年和月的汇总完成了工作

答案 1 :(得分:0)

类似于上面的方法。提示:您可以分别执行两个子查询,以分析逻辑。

select to_char (m.month, 'yyyymm') as TMONTH, m.month, 
       nvl (h.qtn, 0) as QTN
from 
(
  SELECT add_months(trunc (SYSDATE, 'MONTH'), -(LEVEL-1)) as MONTH 
    FROM dual 
    CONNECT BY LEVEL <= 12 -- generate a list of the last 12 month
) m
left join 
(
  SELECT trunc (closure_date, 'MONTH') as MONTH,
         count (*) as QTN
    FROM Holidays
    group by trunc (closure_date, 'MONTH')
) h
on m.MONTH = h.MONTH
where m.month between DATE '2016-01-01' and sysdate
order by TMONTH desc;