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
.
你可以在几天内使用类似的逻辑
我很难理解 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
.
你可以在几天内使用类似的逻辑