Return default value if there is no record

4

I have the following sql command from select:

SELECT 
    public.controleimpressoes.codigo, 
    public.impressoras.patrimonio, 
    public.impressoramodelo.modelo,
    public.impressoralocal.descricao,
   (select SUBSTR((to_char(data - interval '1 month', 'TMMonth')),1,3))dataMes,
    diferecacontador, 
    diferecacontadordigital, 
    diferencacontadorcolor,
    public.empresa.nome, 
    datainicial, 
    datafinal
FROM 
    public.controleimpressoes, public.impressoras, public.impressoramodelo,
    public.impressoralocal, public.empresa
where 
    public.controleimpressoes.codigoempresa = public.empresa.codigo and
    public.controleimpressoes.codigoimpressora = public.impressoras.codigo and
    public.impressoras.codigomodelo = public.impressoramodelo.codigo and 
    public.controleimpressoes.codigoimpressoralocal = public.impressoralocal.codigo  and
    data between '2017-01-01' and  '2017-12-31'  and
    public.impressoras.patrimonio between '1000' and '1882' and
    public.empresa.nome between 'A' and 'B' and 
    public.impressoramodelo.modelo between 'C748' and 'C748' 
order by 
    public.empresa.nome, public.impressoras.patrimonio, data

And the same returns me the following:

Isitpossibletoadjustthisquerysothatwhenthereisnorecordinthemonthmeisreturned0asthedefaultvalue?

Somethingsimilartothis:

Where February would have no record.

    
asked by anonymous 08.03.2018 / 18:58

2 answers

3

You can use the generate_series function to generate the numbers from 1 to 12 (months) and from them, fetch your records. See:

select
    g,
    to_char( to_timestamp(to_char(g, '999'), 'MM'), 'TMMon') as mes, 
    count(r.id) as qtd
from generate_series(1,12) g
left outer join registros r on extract(month from r.data) = g
group by g
order by g

Test Data:

  create table registros
  (
  id int,
  data timestamp
  );

  insert into registros values (1,'2018/01/01');
  insert into registros values (2,'2018/01/01');
  insert into registros values (3,'2018/02/01');
  insert into registros values (4,'2018/02/01');
  insert into registros values (5,'2018/02/01');
  insert into registros values (6,'2018/04/01');
  insert into registros values (7,'2018/05/01');
  insert into registros values (8,'2018/06/01');

Result:

Iputitin SQLFiddle

  

You do not need SUBSTR to abbreviate the month, just change TMMonth to TMMon

  

On the other answer, the COALESCE(NULLIF(seuCampo,'') , '0' ) is wrong. The two functions do the same thing, it would suffice: COALESCE(seuCampo , '0')

  

The generate_series function also accepts TIMESTAMP as a parameter, which in the case of months, facilitates =]

Reference: link

Edit:

For your code, I believe it might look like this (I could not test for not having the structure of the tables):

Basically, save the data you need in a temporary table, then make a left join with the function:

  

There were more requests for the chat, and they were implemented in the code:

with dados as ( 
SELECT 
    public.controleimpressoes.codigo, 
    public.impressoras.patrimonio, 
    public.impressoramodelo.modelo, 
    public.impressoralocal.descricao, 
    data, 
    diferecacontador, 
    diferecacontadordigital, 
    diferencacontadorcolor, 
    public.empresa.nome, 
    datainicial, 
    datafinal 
FROM 
public.controleimpressoes, public.impressoras, public.impressoramodelo, 
public.impressoralocal, public.empresa 
where 
public.controleimpressoes.codigoempresa = public.empresa.codigo and 
public.controleimpressoes.codigoimpressora = public.impressoras.codigo and 
public.impressoras.codigomodelo = public.impressoramodelo.codigo and 
public.controleimpressoes.codigoimpressoralocal = public.impressoralocal.codigo and 
data between '2017-01-01' and '2017-12-31' and 
public.impressoras.patrimonio between '1000' and '1882' and 
public.empresa.nome between 'A' and 'B' and 
public.impressoramodelo.modelo between 'C748' and 'C748' 
), meses as (

Select distinct
    intervalo,
    d.patrimonio,
    d.modelo,
    d.descricao,
    d.nome
FROM generate_series('2017-01-01'::timestamp, '2017-12-31'::timestamp, '1 Month') as intervalo 
CROSS JOIN dados d)


SELECT DISTINCT
    to_char(intervalo , 'TMMon') dataMes, 
    m.*,
    d.diferecacontador, 
    d.diferecacontadordigital, 
    d.diferencacontadorcolor, 
    d.datainicial,
    d.datafinal
FROM meses m
LEFT OUTER JOIN DADOS d on date_trunc('month',d.data) = m.intervalo and m.patrimonio = d.patrimonio
order by m.nome, m.patrimonio, d.data
  

Result:

    
08.03.2018 / 19:48
0

If you refer to the column, try doing this:

COALESCE( NULLIF(seuCampo,'') , '0' )

NULLIF compares if the field passed in the first parameter is equal to empty, and for it it places 0 instead of the value. You replace these empty quotes with any value, in your case I think it would be '0.0'.

    
08.03.2018 / 19:04