MySQL 5.6 选择月份和日期

MySQL 5.6 Selecting months and days

我很难理解 MySQL 的日期函数。

比如我想获取本月和上个月的所有记录

根据我的理解,我应该使用 MONTH(NOW()),其中 returns 是当前月份的整数,MONTH(NOW())-1 是上个月的整数。除了在 1 月份询问日期时,这显然不会起作用,因为它是对函数的结果执行的,而不是环绕并转到上一年的 12 月。

我将如何着手编写一个也可以在 1 月运行的通用函数?由于月份的长度不同,因此无法从 NOW() I recon.

中减去一个月(以毫秒为单位)

例如,除了 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() 函数也出现了类似的问题,因为月份的长度各不相同,每天写语句似乎效率不高。

为任何感兴趣的月份的每一天选择记录的更有效方法是什么,而不管该特定日期是否实际有记录?

您的逻辑对于其他年份的日期也不安全。 实现你想要的方法可能是将日期截断到一个月的第一天,例如(将 NOW 替换为 2013-01-20

select table_date, 
case when date_format(table_date, '%Y-%m-01') 
  = date_format('2013-01-20', '%Y-%m-01') then 1 end AS THIS_MONTH,
case when date_format(table_date, '%Y-%m-01')
  = date_add(date_format('2013-01-20', '%Y-%m-01'), interval -1 month) then 1 end AS LAST_MONTH
from x;

看到这个SqlFiddle

你能试试这个吗:

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)

您很容易从所有年份中提取记录,而不仅仅是 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)

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

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

一个月试试这个:sum(case when month(table_date) = month(date_sub(curdate(), interval 1 month)) then 1 else 0 end) as last_month.

你可以在几天内使用类似的逻辑