从日期范围中选择9月份的年份

时间:2014-09-24 21:45:31

标签: mysql

我有一张开始日期和结束日期表 - 大多数是一整年,但从任何一个月开始。

我想获得一份关于每年当月活跃行数的报告。它将像计数 - 当前,计数去年,计数2年前等

我在PHP中构建我的查询,因此我可以轻松地使用sum(在结束时的情况)和硬编码的日期或子查询的总和,但我认为可能有更好的方法。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

您可以使用表达式而不是“日期中的硬代码”

要返回当前月份的第一个日期,您可以使用一个表达式返回当前日期的年份和月份,并使用固定值替换当月的第一个日期,如下所示:

DATE_FORMAT(NOW(),'%Y-%m-01')

要在那之前一年

DATE_FORMAT(NOW(),'%Y-%m-01') - INTERVAL 1 YEAR

对于范围比较,要检查是否存在“重叠”(表中每行的start_dateend_date之间的时间段),以及给定月份的第一天和最后一天,我会做这样的事情:

     end_date >= DATE_FORMAT(NOW(),'%Y-%m-01')
AND start_date < DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL 1 MONTH 

此模式(大于或等于月的第一个月且小于下个月的第一个月)适用于日期以及包含时间组件的日期时间。 (此检查假定end_date的NULL值未用于表示“无结束日期”...需要调整检查以适应该值。)

如果我有规范(正如我解释的那样),我可能会这样做:

 SELECT SUM( t.start_date   < DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL   1 MONTH
         AND t.end_date    >= DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL   0 MONTH
        ) AS `count_current_year`

      , SUM( t.start_date   < DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL -11 MONTH
         AND t.end_date    >= DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL -12 MONTH
        ) AS `count_previous_year`

      , SUM( t.start_date   < DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL -23 MONTH
         AND t.end_date    >= DATE_FORMAT(NOW(),'%Y-%m-01') + INTERVAL -24 MONTH
        ) AS `count_two_years_ago`

  FROM mytable t

我不知道这更好。 (这可能比你拥有的更加丑陋,但我不认为那里有什么东西是残酷的。)

我没有看到在start_dateend_date上有效使用索引的方法(给定一行代表“日期范围”),除非完全可以从索引中完成查询(即存在覆盖指数。)

答案 1 :(得分:0)

对于它的价值,您可以使用此字符串检索当月发生任何DATEDATETIMETIMESTAMP项目的第一天。

 DATE(DATE_FORMAT(when, '%Y-%m-01'))

这个小函数在GROUP BY表达式等中非常有用。