Search code examples
sqloracle-databasegroup-bynvl

Need query to return zero when count(*) doesn't match any records


SELECT COUNT(*),TRUNC(TEST_DATE_CREATE) 
FROM TEST_TABLE 
WHERE TEST_DATE_CREATE > (SYSDATE - 10)
GROUP BY TRUNC(TEST_DATE_CREATE);

I need the above query to return the count 0 in case of no records present for a particular date. This doesn't seem to be happening.

I tried NVL, decode. Found that the issue is due to group by clause, but not sure how to fix this.

Please help !!


Solution

  • You need to generate a list of the dates you're interested in, and then do a left outer join to your table to find records that match each date. Something like this:

    with tmp_dates as (
        select trunc(sysdate) - level + 1 as tmp_date
        from dual
        connect by level <= 10
    )
    select count(tt.test_date_create), td.tmp_date
    from tmp_dates td
    left join test_table tt on trunc(tt.test_date_create) = td.tmp_date
    group by td.tmp_date
    order by tmp_date;
    

    The common table expression on its own generates a list of dates:

    select trunc(sysdate) - level + 1 as tmp_date
    from dual
    connect by level <= 10;
    
    TMP_DATE
    ---------
    10-JUN-13 
    09-JUN-13 
    08-JUN-13 
    07-JUN-13 
    06-JUN-13 
    05-JUN-13 
    04-JUN-13 
    03-JUN-13 
    02-JUN-13 
    01-JUN-13 
    

    You can adjust the level limit and how it's added to sysdate to modify the range, e.g. to look further back or to exclude today.

    The main select then uses that to look for matching records. Because it is an outer join it lists all the generated dates, and a count of zero where there are no matches.

    SQL Fiddle.