SQL Fill empty query with 0 based on date range

176 views Asked by At

I have the following Oracle SQL query results:

TDATE OPEN Closed 19/05/15 1 1 20/05/15 0 1 26/05/15 2 0 27/05/15 1 0 28/05/15 2 0

For example I would like to query from the 19 - 30 May.

And the results i would like to get is:

TDATE OPEN Closed 19/05/15 1 1 20/05/15 0 1 21/05/15 0 0 22/05/15 0 0 23/05/15 0 0 24/05/15 0 0 25/05/15 0 0 26/05/15 2 0 27/05/15 1 0 28/05/15 2 0 29/05/15 0 0 30/05/15 0 0

Where the query is within the date range and records that do not exist will be returned as 0 and 0 for Open and Closed.

Any help would be appreciated.

2

There are 2 answers

0
Joop Eggen On

An empty table with zeroes and all the dates could be made as

INSERT INTO empytable
(SELECT TRUNC(@firstdat + (ROWNUM - 1)) dat, 0, 0
FROM DUAL CONNECT BY ROWNUM <= @days)

Then you can load your results into this table, or combine them otherwise. The placeholder firstdat should be a date for the addition to work.

0
San On

In Oracle, using CTE,

WITH table_ (TDATE, OPEN, Closed) AS (
SELECT to_date('19/05/15', 'dd/mm/yy'), 1, 1 from dual UNION ALL
SELECT to_date('20/05/15', 'dd/mm/yy'), 0, 1 from dual UNION ALL
SELECT to_date('26/05/15', 'dd/mm/yy'), 2, 0 from dual UNION ALL
SELECT to_date('27/05/15', 'dd/mm/yy'), 1, 0 from dual UNION ALL
SELECT to_date('28/05/15', 'dd/mm/yy'), 2, 0 from dual),
--------------
-- End of data preparation
--------------
arr_table as (
select to_date('19/05/15', 'dd/mm/yy') + level - 1 dummy_date
  from dual 
connect by ROWNUM < = to_date('28/05/15', 'dd/mm/yy') - to_date('19/05/15', 'dd/mm/yy') + 1)
SELECT a.dummy_date, COALESCE( b.open, 0) AS OPEN,  COALESCE( b.closed, 0) AS closed
  FROM arr_table a
  LEFT OUTER JOIN table_ b
    ON b.tdate = a.dummy_date
ORDER BY  a.dummy_date;

Output:

|            DUMMY_DATE | OPEN | CLOSED |
|-----------------------|------|--------|
| May, 19 2015 00:00:00 |    1 |      1 |
| May, 20 2015 00:00:00 |    0 |      1 |
| May, 21 2015 00:00:00 |    0 |      0 |
| May, 22 2015 00:00:00 |    0 |      0 |
| May, 23 2015 00:00:00 |    0 |      0 |
| May, 24 2015 00:00:00 |    0 |      0 |
| May, 25 2015 00:00:00 |    0 |      0 |
| May, 26 2015 00:00:00 |    2 |      0 |
| May, 27 2015 00:00:00 |    1 |      0 |
| May, 28 2015 00:00:00 |    2 |      0 |

So basically, the query will be :

with arr_table as (
    select to_date(<start_date>, 'dd/mm/yy') + level - 1 dummy_date
      from dual 
    connect by ROWNUM < = to_date(<end_date>, 'dd/mm/yy') - to_date(<start_date>, 'dd/mm/yy') + 1)
    SELECT a.dummy_date, COALESCE( b.open, 0) AS OPEN,  COALESCE( b.closed, 0) AS closed
      FROM arr_table a
      LEFT OUTER JOIN <your_table> b
        ON b.tdate = a.dummy_date
    ORDER BY  a.dummy_date;