MySQL 5.6选择月和日

时间:2016-09-17 10:30:13

标签: mysql sql date mysql-5.6

我很难理解MySQL的日期功能。

例如,我想获得本月和上个月的所有记录。

根据我的理解,我应该使用MONTH(NOW())来返回当月的整数和前一个月的MONTH(NOW())-1。除了在1月份要求提供日期之外,这显然不会起作用,因为它是对功能的结果执行而不是环绕并前往去年12月。

我如何编写一月份也可以使用的通用函数?由于几个月的长度各不相同,因此无法从NOW()我重新调整后的一个月内减去一个月。

例如,此查询在1月份正常工作:

SELECT
          SUM(CASE WHEN MONTH(table_date) = MONTH(NOW())-1 THEN 1 ELSE 0 END) AS LAST_MONTH,
          SUM(CASE WHEN MONTH(table_date) = MONTH(NOW()) THEN 1 ELSE 0 END) AS THIS_MONTH
          FROM table
          WHERE table_date BETWEEN Date_add(NOW(), interval - 1 month) AND  NOW()

类似的问题出现在DAY()函数中,因为几个月的长度各不相同,每天写作语句看起来效率都不高。

对于任何感兴趣的月份的每一天选择记录的更有效方法是什么,无论该特定日期是否确实有记录?

4 个答案:

答案 0 :(得分:1)

对于其他年份的日期,您的逻辑也不安全。 实现目标的方法可能是将日期截断到本月的第一天,例如(替换liftNOW

2013-01-20

请参阅此SqlFiddle

答案 1 :(得分:1)

您很容易从所有年份中提取记录,而不仅仅是table_date中存储的当前记录。要摆脱它,您需要在年份上进行操作,这可以通过始终计算正确的日期格式YYYY-MM-DD来完成,而不会失去精确度。

以下是用于构建最终查询的一些计算。

每月的第一天:

SELECT DATE_FORMAT(table_date, '%Y-%m-01') FROM table

上个月的第一天:

SELECT DATE_FORMAT(DATE_SUB(table_date, INTERVAL 1 MONTH), '%Y-%m-01') FROM table

每月的最后一天:

SELECT LAST_DAY(table_date) FROM table

上个月的最后一天:

SELECT LAST_DAY(DATE_SUB(table_date, INTERVAL 1 MONTH)) FROM table

您的最终查询:

SELECT
  SUM(CASE WHEN table_date BETWEEN DATE_FORMAT(table_date, '%Y-%m-01') AND LAST_DAY(table_date) THEN 1 END) AS this_month,
  SUM(CASE WHEN table_date BETWEEN DATE_FORMAT(DATE_SUB(table_date, INTERVAL 1 MONTH), '%Y-%m-01') AND LAST_DAY(DATE_SUB(table_date, INTERVAL 1 MONTH)) THEN 1 END) AS last_month
FROM table
WHERE 
  table_date BETWEEN 
   DATE_FORMAT(DATE_SUB(table_date, INTERVAL 1 MONTH), '%Y-%m-01')
   AND LAST_DAY(table_date)

注意:在案例表达式中,我省略了ELSE 0,因为CASE中ELSE的默认语句为空,SUM()忽略空值: - )

答案 2 :(得分:1)

您的逻辑将日期转换为整数,然后从中减去1。对于像1月那样的日期和月份,该值变为1.如果减去1,则从该值变为零,这不是有效的日期或月份。

对于月份,请尝试:sum(case when month(table_date) = month(date_sub(curdate(), interval 1 month)) then 1 else 0 end) as last_month

你可以使用类似的逻辑

答案 3 :(得分:0)

请你试试这个:

SELECT table_date, 
SUM(CASE WHEN (LEFT(table_date, 7) = LEFT(NOW(),7)) THEN 
        1 
    ELSE 0 END) AS THIS_MONTH,
SUM(CASE WHEN 
    (LEFT(table_date, 7) = LEFT(DATE_SUB(NOW(), INTERVAL 1 MONTH),7)) THEN 
    1 ELSE 0 END) AS LAST_MONTH
FROM table
WHERE LEFT(table_date, 7) BETWEEN LEFT(DATE_SUB(NOW(), INTERVAL 1 MONTH),7) 
AND LEFT(NOW(),7)