选择给定日期范围内的所有月份,包括值为0的月份

时间:2010-06-22 14:10:17

标签: mysql date group-by between

我正在尝试编写MySQL查询以获得每月平均值,以及给定日期之间的所有月份。我的想法是:

查询,例如

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

你看,在2009年4月期间没有输入任何值,但我希望它在输出中显示为0,0值。关于如何实现这一点的任何想法?可以在MySQL内完成吗?

2 个答案:

答案 0 :(得分:6)

我同意Lieven的答案创建一个包含您可能需要的所有月份的表格,并将其用于“LEFT JOIN”到您的结果表。请记住,这是一个非常小的表,每年只有365(ish)行的数据......你可以轻松编写一些代码来填充这个表最初

我们在这里这样做,并且它提供了很多好处,例如,想象一个包含以下字段的月度数据表(以及您能想到的任何其他字段!)在给定范围内的所有月份完全填充;

  • 日期(例如2009-04-01)
  • Day(例如1)
  • 星期几(例如星期三)
  • 月(例如4)
  • 年(例如,2009年)
  • 财政年度(例如2009/10)
  • 财政季度(例如2009Q1)
  • 日历季(例如2009Q2)

然后将其与上面的查询相结合,如下所示;

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

FROM `dateTable` as DT
LEFT JOIN `myTable`
    ON `dateTable`.`myDate` = `myTable`.`save_date`

WHERE `dateTable`.`myDate` BETWEEN '2009-01-01' AND '2009-07-01'

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

我的SQL代码中可能存在一些错误,因为我无法创建测试表,但希望您能获得主体并根据您的需求进行更改!

使用此功能,您可以将“GROUP BY”子句更改为“dateTable”表中的任何内容,这样您就可以按财务季度,月份,日期,星期几等轻松报告。

希望有所帮助!

答案 1 :(得分:2)

最简单的方法可能是创建一个包含月份和年份的日期表,并将其与最终结果结合起来。