I have the tables below and I need my query to bring me the amount of operations grouped by date. For the dates on which there will be no operations, I need to return the date anyway with the zero count. Kind like that:
OPERATION_DATE | COUNT_OPERATION | COUNT_OPERATION2 | 04/06/2019 | 453 | 81 | 05/06/2019 | 0 | 0 |
— QUERY I TRIED
SELECT 
    T1.DATE_OPERATION AS  DATE_OPERATION,
    NVL(T1.COUNT_OPERATION, '0') COUNT_OPERATION,
    NVL(T1.COUNT_OPERATION2, '0') COUNT_OPERATIONX,
FROM
(  
SELECT
    trunc(t.DATE_OPERATION) as DATE_OPERATION,
    count(t.ID_OPERATION) AS COUNT_OPERATION,
    COUNT(CASE WHEN O.OPERATION_TYPE = 'X' THEN 1 END) COUNT_OPERATIONX,
from OPERATION o
    left join OPERATION_TYPE ot on ot.id_operation = o.id_operation
where ot.OPERATION_TYPE in ('X', 'W', 'Z', 'I', 'J', 'V') 
    and TRUNC(t.DATE_OPERATION) >= to_date('01/06/2019', 'DD-MM-YYYY')
    group by trunc(t.DATE_OPERATION)
) T1
— TABLES
CREATE TABLE OPERATION
(   ID_OPERATION NUMBER NOT NULL,
    DATE_OPERATION DATE NOT NULL,
    VALUE NUMBER NOT NULL )
CREATE TABLE OPERATION_TYPE
(   ID_OPERATION NUMBER NOT NULL,
    OPERATION_TYPE VARCHAR2(1) NOT NULL,
    VALUE NUMBER NOT NULL)  
Advertisement
Answer
I guess that it is a calendar you need, i.e. a table which contains all dates involved. Otherwise, how can you display something that doesn’t exist?
This is what you currently have (I’m using only the operation table; add another one yourself):
SQL> with 2 operation (id_operation, date_operation, value) as 3 (select 1, date '2019-06-01', 100 from dual union all 4 select 2, date '2019-06-01', 200 from dual union all 5 -- 02/06/2019 is missing 6 select 3, date '2019-06-03', 300 from dual union all 7 select 4, date '2019-06-04', 400 from dual 8 ) 9 select o.date_operation, 10 count(o.id_operation) 11 from operation o 12 group by o.date_operation 13 order by o.date_operation; DATE_OPERA COUNT(O.ID_OPERATION) ---------- --------------------- 01/06/2019 2 03/06/2019 1 04/06/2019 1 SQL>
As there are no rows that belong to 02/06/2019, query can’t return anything (you already know that).
Therefore, add a calendar. If you already have that table, fine – use it. If not, create one. It is a hierarchical query which adds level to a certain date. I’m using 01/06/2019 as the starting point, creating 5 days (note the connect by clause). 
SQL> with 2 operation (id_operation, date_operation, value) as 3 (select 1, date '2019-06-01', 100 from dual union all 4 select 2, date '2019-06-01', 200 from dual union all 5 -- 02/06/2019 is missing 6 select 3, date '2019-06-03', 300 from dual union all 7 select 4, date '2019-06-04', 400 from dual 8 ), 9 dates (datum) as --> this is a calendar 10 (select date '2019-06-01' + level - 1 11 from dual 12 connect by level <= 5 13 ) 14 select d.datum, 15 count(o.id_operation) 16 from operation o full outer join dates d on d.datum = o.date_operation 17 group by d.datum 18 order by d.datum; DATUM COUNT(O.ID_OPERATION) ---------- --------------------- 01/06/2019 2 02/06/2019 0 --> missing in source table 03/06/2019 1 04/06/2019 1 05/06/2019 0 --> missing in source table SQL>
Probably a better option is to dynamically create a calendar so that it doesn’t depend on any hardcoded values, but uses the min(date_operation) to max(date_operation) time span. Here we go:
SQL> with 2 operation (id_operation, date_operation, value) as 3 (select 1, date '2019-06-01', 100 from dual union all 4 select 2, date '2019-06-01', 200 from dual union all 5 -- 02/06/2019 is missing 6 select 3, date '2019-06-03', 300 from dual union all 7 select 4, date '2019-06-04', 400 from dual 8 ), 9 dates (datum) as --> this is a calendar 10 (select x.min_datum + level - 1 11 from (select min(o.date_operation) min_datum, 12 max(o.date_operation) max_datum 13 from operation o 14 ) x 15 connect by level <= x.max_datum - x.min_datum + 1 16 ) 17 select d.datum, 18 count(o.id_operation) 19 from operation o full outer join dates d on d.datum = o.date_operation 20 group by d.datum 21 order by d.datum; DATUM COUNT(O.ID_OPERATION) ---------- --------------------- 01/06/2019 2 02/06/2019 0 --> missing in source table 03/06/2019 1 04/06/2019 1 SQL>