我很难理解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()
函数中,因为几个月的长度各不相同,每天写作语句看起来效率都不高。
对于任何感兴趣的月份的每一天选择记录的更有效方法是什么,无论该特定日期是否确实有记录?
答案 0 :(得分:1)
答案 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)