Skip to Main Content
  • Questions
  • How to display zero as count if there is no record in data base in combination with Date column?

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Siva.

Asked: August 31, 2016 - 3:53 am UTC

Last updated: August 31, 2016 - 7:51 am UTC

Version: Oracle 11g

Viewed 10K+ times! This question is

You Asked

Hello,

After executing the Query Month Starts from APR to SEP only data is available in database and displaying properly.
If there is no data i would like to display Month and Count as 0 with the same result.
Ex: Here January(01) month has no record in database It should display like below,similar to December(12) month too.

YEAR MONTH TOTAL_PAGE_VISITOR
2015 01 0
2015 02 8
2015 03 176
2015 04 369
2015 05 130
2015 06 148
2015 07 296
2015 08 44
2015 09 44
2015 11 38
2015 12 0

SELECT to_char(Cns.Requestdate,'YYYY') As Year,to_char(Cns.Requestdate,'MM') As Month,SUM(Cns.Pagevisitors) AS TOTAl_PAGE_VISITOR FROM Shortid Sh
INNER JOIN Countername Cn ON Sh.Id = Cn.Shortid_id
INNER JOIN Countername_Summary Cns ON Cn.Id = Cns.Countername_Id
INNER JOIN Countrycode Cd ON Cd.Id = Cn.Countrycode_Id
WHERE Cns.Pagevisitors IS NOT NULL AND to_char(Cns.Requestdate,'YYYY') ='2015'
AND Sh.Shortid like '%wcms_bnn_-news_detail_page-%'
GROUP BY to_char(Cns.Requestdate, 'YYYY'),TO_CHAR(Cns.Requestdate, 'MM')
ORDER BY TO_CHAR(Cns.Requestdate, 'MM') ASC;

How to modify the query to get the 0 in the count with month and year?
Thank you.

How to get the

and Connor said...

First we'll create a table that is "missing" some months


SQL> drop table t purge;

Table dropped.

SQL>
SQL> create table t as
  2  select rownum r, add_months(date '2016-01-01',rownum-1) dte, ceil(dbms_random.value(0,100)) amt
  3  from dual
  4  connect by level <= 12;

Table created.

SQL>
SQL> select * from t;

         R DTE              AMT
---------- --------- ----------
         1 01-JAN-16         25
         2 01-FEB-16         69
         3 01-MAR-16          9
         4 01-APR-16         45
         5 01-MAY-16         47
         6 01-JUN-16         78
         7 01-JUL-16         30
         8 01-AUG-16         64
         9 01-SEP-16         19
        10 01-OCT-16         36
        11 01-NOV-16         93
        12 01-DEC-16         17

12 rows selected.

SQL>
SQL> delete from t
  2  where  r in ( 1,4,6 );

3 rows deleted.

SQL>
SQL> select * from t;

         R DTE              AMT
---------- --------- ----------
         2 01-FEB-16         69
         3 01-MAR-16          9
         5 01-MAY-16         47
         7 01-JUL-16         30
         8 01-AUG-16         64
         9 01-SEP-16         19
        10 01-OCT-16         36
        11 01-NOV-16         93
        12 01-DEC-16         17

9 rows selected.


To fill in the blanks, we need something that has the full 12 months so we can outer join from it to "T". But we just saw above how to generate 12 months of rows, so we can use the same concept:


SQL>
SQL>
SQL> with all_the_months as
  2  (
  3    select add_months(date '2016-01-01',rownum-1) mth
  4    from dual
  5    connect by level <= 12
  6  )
  7  select a.mth, nvl(t.amt,0)
  8  from   t,
  9         all_the_months a
 10  where  a.mth = t.dte(+)
 11  order by 1;

MTH       NVL(T.AMT,0)
--------- ------------
01-JAN-16            0
01-FEB-16           69
01-MAR-16            9
01-APR-16            0
01-MAY-16           47
01-JUN-16            0
01-JUL-16           30
01-AUG-16           64
01-SEP-16           19
01-OCT-16           36
01-NOV-16           93
01-DEC-16           17

12 rows selected.

SQL>



Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Other Option | Model

Rajeshwaran Jeyabal, August 31, 2016 - 12:16 pm UTC

demo@ORA12C> select * from t;

         X Y                    Z
---------- ----------- ----------
         2 01-FEB-2016         86
         3 01-MAR-2016         75
         5 01-MAY-2016         35
         7 01-JUL-2016         70
         8 01-AUG-2016         19
         9 01-SEP-2016         63
        10 01-OCT-2016         38
        11 01-NOV-2016         38
        12 01-DEC-2016         95

9 rows selected.

demo@ORA12C> select *
  2  from t
  3  model
  4     dimension by (y)
  5     measures (z)
  6     rules(
  7             z[for y from to_date('01-Jan-2016','dd-mon-yyyy') to
  8                             to_date('01-dec-2016','dd-mon-yyyy')
  9                             increment numtoyminterval(1,'month')]
 10             = nvl(z[cv()],0) )
 11  order by y ;

Y                    Z
----------- ----------
01-JAN-2016          0
01-FEB-2016         86
01-MAR-2016         75
01-APR-2016          0
01-MAY-2016         35
01-JUN-2016          0
01-JUL-2016         70
01-AUG-2016         19
01-SEP-2016         63
01-OCT-2016         38
01-NOV-2016         38
01-DEC-2016         95

12 rows selected.

demo@ORA12C>

More to Explore

DBMS_RANDOM

More on PL/SQL routine DBMS_RANDOM here