sql – Show value 0 when no data

Question:

How to show in a sql query, value 0 when there is no data in the table?

SELECT
ae.dt_data,                  
to_char(ae.dt_data, 'dy'),
case
when to_char(ae.dt_data, 'dy') = 'sun' then 'Domingo'
when to_char(ae.dt_data, 'dy') = 'mon' then 'Segunda'
when to_char(ae.dt_data, 'dy') = 'tue' then 'Terça'
when to_char(ae.dt_data, 'dy') = 'wed' then 'Quarta'
when to_char(ae.dt_data, 'dy') = 'thu' then 'Quinta'
when to_char(ae.dt_data, 'dy') = 'fri' then 'Sexta'
when to_char(ae.dt_data, 'dy') = 'sat' then 'Sabado'
end as dia_semana,
count(DISTINCT ae.nr_controle) as qtde
                                       
FROM atendimentos  ae                                        
join exames        ex using(cd_atendimento)                
join procedimentos pr using(cd_procedimento)                 
join modalidades   mo using(cd_modalidade)                   
join pacientes     pa using(cd_paciente)                     
join salas         sa using(cd_sala)                         
join medicos       me on me.cd_medico = ae.cd_medico         
join planos        pl on pl.cd_plano  = ex.cd_plano          
join empresas      em on sa.cd_empresa = em.cd_empresa left  
join medicos       ms on ms.cd_medico = ex.cd_medico   left  
join atendimentos_localizacao al on al.cd_localizacao = ae.cd_localizacao

WHERE ae.dt_data >= now() :: date - 7 AND ae.dt_data < now() :: date

and  sa.cd_empresa = 7
and  ae.cd_sala in (74, 4, 121, 6, 7, 8, 75, 122, 91, 11, 111, 12, 134)
and  pr.cd_modalidade in (40, 14, 12, 19, 18, 15, 38, 17, 33, 20, 1, 16, 64)
and  pr.cd_procedimento in (627, 628, 631, 629, 635, 634, 630, 633, 632, 636, 669, 915, 604, 620, 616, 606, 608, 625, 610, 646, 828, 770, 614, 1013, 735, 618, 826)
and  ae.nr_controle is not null -- Descarta pacientes que não foram atendidos (Roxo ou Preto)

group by dt_data

In this query above, he provides me with this data:

Dia_semana  |   qtde
Quinta      |   57
Sexta       |   64
Sabado      |   1
Segunda     |   80
Terça       |   64
Quarta      |   54

As Domingo had no data to be consulted, he did not show it in the result. I would like Sunday = 0, like the example below for days of the week that do not have data.

Dia_semana  |   qtde
Quinta      |   57
Sexta       |   64
Sabado      |   1
Domingo     |   0
Segunda     |   80
Terça       |   64
Quarta      |   54

I've already tried to consult using coalesce and I couldn't.

The bank is Postgres.

Answer:

Making a left outer join with a fake table should solve…

WITH vazio as 
(
  SELECT NOW() dt_data UNION ALL
  SELECT NOW() - INTERVAL '1 day' dt_data UNION ALL
  SELECT NOW() - INTERVAL '2 day' dt_data UNION ALL
  SELECT NOW() - INTERVAL '3 day' dt_data UNION ALL
  SELECT NOW() - INTERVAL '4 day' dt_data UNION ALL
  select NOW() - INTERVAL '5 day' dt_data UNION ALL
  SELECT NOW() - INTERVAL '6 day' dt_data
)

select v.dt_data, 
       case
        when to_char(v.dt_data, 'dy') = 'sun' then 'Domingo'
        when to_char(v.dt_data, 'dy') = 'mon' then 'Segunda'
        when to_char(v.dt_data, 'dy') = 'tue' then 'Terça'
        when to_char(v.dt_data, 'dy') = 'wed' then 'Quarta'
        when to_char(v.dt_data, 'dy') = 'thu' then 'Quinta'
        when to_char(v.dt_data, 'dy') = 'fri' then 'Sexta'
        when to_char(v.dt_data, 'dy') = 'sat' then 'Sabado'
        end as dia_semana,
       count(DISTINCT ae.nr_controle) as qtde
  from vazio v
  left outer join atendimentos ae
    on cl.dat_err :: date = v.dt_data :: date
  join exames        ex using(cd_atendimento)                
  join procedimentos pr using(cd_procedimento)                 
  join modalidades   mo using(cd_modalidade)                   
  join pacientes     pa using(cd_paciente)                     
  join salas         sa using(cd_sala)                         
  join medicos       me 
    on me.cd_medico = ae.cd_medico         
  join planos        pl 
    on pl.cd_plano  = ex.cd_plano          
  join empresas      em 
    on sa.cd_empresa = em.cd_empresa 
  left outer join medicos ms 
    on ms.cd_medico = ex.cd_medico   left  
  join atendimentos_localizacao al on al.cd_localizacao = ae.cd_localizacao
 WHERE ae.dt_data >= now() :: date - 7 AND ae.dt_data < now() :: date
   and sa.cd_empresa = 7
   and ae.cd_sala in (74, 4, 121, 6, 7, 8, 75, 122, 91, 11, 111, 12, 134)
   and pr.cd_modalidade in (40, 14, 12, 19, 18, 15, 38, 17, 33, 20, 1, 16, 64)
   and pr.cd_procedimento in (627, 628, 631, 629, 635, 634, 630, 633, 632, 636, 669, 915, 604, 620, 616, 606, 608, 625, 610, 646, 828, 770, 614, 1013, 735, 618, 826)
   and  ae.nr_controle is not null -- Descarta pacientes que não foram atendidos (Roxo ou Preto)
 group by v.dt_data :: date

PS: As you don't have the script of the tables, I haven't tested it with this query. But I believe it will work too.

Scroll to Top