Selecione todos os meses dentro do intervalo de datas, incluindo aqueles com valores 0

Eu estou tentando escrever uma consulta MySQL para obter um valor médio por mês, para todos os meses entre as datas dadas. Minha ideia é esta:

Consulta, algo como

SELECT AVG(value1) as avg_value_1, AVG(value2) as avg_value_2, MONTH(save_date) as month, YEAR(save_date) as year FROM myTable WHERE save_date BETWEEN '2009-01-01' AND '2009-07-01' GROUP BY YEAR(save_date), MONTH(save_date) avg_value_1 | avg_value_2 | month | year 5 | 4 | 1 | 2009 2 | 1 | 2 | 2009 7 | 5 | 3 | 2009 0 | 0 | 4 | 2009 <--- 6 | 5 | 5 | 2009 3 | 6 | 6 | 2009 

Você vê, nenhum valor foi inserido durante abril de 2009, mas eu quero que ele apareça como um valor 0, 0 na saída. Alguma idéia de como conseguir isso? Isso pode ser feito dentro do MySQL?

Eu concordo com a resposta de Lieven para criar uma tabela contendo todos os meses que você poderia precisar, e use isso para “LEFT JOIN” na sua tabela de resultados. Lembre-se, esta é uma tabela muito pequena, apenas 365 (ish) linhas por ano de dados que você tem … E você pode facilmente escrever algum código para preencher essa tabela inicialmente

Fazemos isso aqui e ele oferece muitos benefícios, por exemplo, imagine uma tabela de dados mensal com os seguintes campos (e todos os outros que você pode imaginar!) Totalmente preenchidos para todos os meses em um determinado intervalo;

  • Data (por exemplo, 2009-04-01)
  • Dia (por exemplo 1)
  • Dia da semana (por exemplo, quarta-feira)
  • Mês (por exemplo, 4)
  • Ano (por exemplo, 2009)
  • Exercício Financeiro (por exemplo, 2009/10)
  • Trimestre financeiro (por exemplo, 2009Q1)
  • Trimestre do calendar (por exemplo, 2009Q2)

Em seguida, combine isso com sua consulta acima, da seguinte maneira;

 SELECT `DT``myYear`,` DT``myMonth`, 
            AVG (`myTable``value1`) como avg_value_1, 
            AVG (`myTable``value2`) como avg_value_2

 FROM `dateTable` como DT
 JOGO ESQUERDO `myTable`
     ON `dateTable``myDate` =` myTable``save_date`

 ONDE dateTable``myDate` ENTRE '2009-01-01' E '2009-07-01'

 GROUP BY `DT``myYear`,` DT``myMonth`

Pode haver alguns erros no meu código SQL, pois não consegui criar as tabelas de teste, mas espero que você obtenha o principal e altere para atender às suas necessidades!

Usando isso, você pode alterar sua cláusula “GROUP BY” para qualquer item que você tenha na tabela “dateTable”, o que pode permitir que você relate facilmente por trimestre financeiro, mês, dia, dia da semana, etc.

Espero que ajude!

A maneira mais fácil provavelmente é criar uma tabela de datas contendo meses e anos e unir isso com o resultado final.