【发布时间】:2010-06-09 20:59:10
【问题描述】:
如何在 where 子句中使用下个月的第一天和最后一天?
【问题讨论】:
-
SELECT DATE_ADD(LAST_DAY(NOW()),INTERVAL 1 DAY) AS '下个月的第一天'; SELECT DATE_ADD(LAST_DAY(NOW()),INTERVAL 1 MONTH) AS '下个月的最后一天'
如何在 where 子句中使用下个月的第一天和最后一天?
【问题讨论】:
用途:
SELECT
DATE_SUB(
LAST_DAY(
DATE_ADD(NOW(), INTERVAL 1 MONTH)
),
INTERVAL DAY(
LAST_DAY(
DATE_ADD(NOW(), INTERVAL 1 MONTH)
)
)-1 DAY
) AS firstOfNextMonth,
LAST_DAY(
DATE_ADD(NOW(), INTERVAL 1 MONTH)
)AS lastOfNextMonth
【讨论】:
curdate 而不是now(),因为我们不需要计时。此外,对于第一天,simply minus the number of days of the current month 更直接。它也更快,因为我们只进行了一次date_sub() 调用和一次day() 调用。
下个月的最后一天,可以使用LAST_DAY()函数:
SELECT LAST_DAY(DATE_ADD(CURDATE(), INTERVAL 1 MONTH));
+-------------------------------------------------+
| LAST_DAY(DATE_ADD(CURDATE(), INTERVAL 1 MONTH)) |
+-------------------------------------------------+
| 2010-07-31 |
+-------------------------------------------------+
1 row in set (0.00 sec)
一些经过测试的边缘案例:
SELECT LAST_DAY(DATE_ADD('2010-01-31', INTERVAL 1 MONTH));
+----------------------------------------------------+
| LAST_DAY(DATE_ADD('2010-01-31', INTERVAL 1 MONTH)) |
+----------------------------------------------------+
| 2010-02-28 |
+----------------------------------------------------+
1 row in set (0.00 sec)
SELECT LAST_DAY(DATE_ADD('2010-02-28', INTERVAL 1 MONTH));
+----------------------------------------------------+
| LAST_DAY(DATE_ADD('2010-02-28', INTERVAL 1 MONTH)) |
+----------------------------------------------------+
| 2010-03-31 |
+----------------------------------------------------+
1 row in set (0.00 sec)
SELECT LAST_DAY(DATE_ADD('2010-08-31', INTERVAL 1 MONTH));
+----------------------------------------------------+
| LAST_DAY(DATE_ADD('2010-08-31', INTERVAL 1 MONTH)) |
+----------------------------------------------------+
| 2010-09-30 |
+----------------------------------------------------+
1 row in set (0.00 sec)
还有一个棘手的使用DATE_FORMAT() 函数来获取一个月的第一天。您可以按如下方式使用它:
SELECT DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01');
+---------------------------------------------------------------+
| DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH),'%Y-%m-01') |
+---------------------------------------------------------------+
| 2010-07-01 |
+---------------------------------------------------------------+
1 row in set (0.00 sec)
因此:
SELECT DATE_FORMAT(DATE_ADD(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01') AS
FirstDayOfNextMonth,
LAST_DAY(DATE_ADD(CURDATE(), INTERVAL 1 MONTH)) AS
LastDayOfNextMonth;
+---------------------+--------------------+
| FirstDayOfNextMonth | LastDayOfNextMonth |
+---------------------+--------------------+
| 2010-07-01 | 2010-07-31 |
+---------------------+--------------------+
1 row in set (0.00 sec)
【讨论】:
var_string,而不是日期。请改用我的解决方案。
下个月的第一天就是本月的最后一天+1:
select adddate(last_day(curdate()), 1)
下个月的最后一天就是(今天 + 1 个月)的最后一天:
select last_day(curdate() + interval 1 month))
这些是最直接的解决方案。您将找不到更短的。
如果您需要当前月的第一天,请参阅https://stackoverflow.com/a/28966866/632951
【讨论】:
# FIRST date of next month
select date_sub(date_add(curdate(), interval 1 month), interval day(curdate())-1 day);
# LAST date of next month
select date_sub(date_add(curdate(), interval 2 month), interval day(curdate()) day);
不确定这是最短的查询,但它们确实有效
【讨论】:
正如@DanielVassallo 解释的那样,检索下个月的最后一天很容易:
SELECT LAST_DAY(DATE_ADD(CURRENT_DATE(), INTERVAL 1 MONTH));
要检索第一天,您可以先定义一个自定义的FIRST_DAY 函数(遗憾的是 MySQL 没有提供):
DELIMITER ;;
CREATE FUNCTION FIRST_DAY(day DATE)
RETURNS DATE DETERMINISTIC
BEGIN
RETURN ADDDATE(LAST_DAY(SUBDATE(day, INTERVAL 1 MONTH)), 1);
END;;
DELIMITER ;
然后你可以这样做:
SELECT FIRST_DAY(DATE_ADD(CURRENT_DATE(), INTERVAL 1 MONTH));
【讨论】:
获取下个月的第一个日期:-select LAST_DAY(NOW()) + INTERVAL 1 DAY
获取下个月的最后日期:-select LAST_DAY(NOW()+ INTERVAL 1 Month)
【讨论】:
这里是所有可能的解决方案。希望这会有所帮助......只需运行它以获取所有详细信息
SELECT
DATE_SUB(DATE_FORMAT(NOW(),'%Y-%m-%d'),INTERVAL 1 DAY) AS GetLastDay,
DATE_FORMAT(NOW(),'%Y-%m-%d') AS GetTodaysDate,
DATE_ADD(DATE_FORMAT(NOW(),'%Y-%m-%d'),INTERVAL 7 DAY) AS Add7DaysFromTodaysDate,
DATE_SUB(DATE_FORMAT(NOW(),'%Y-%m-%d'),INTERVAL 7 DAY) AS Substract7DaysFromTodaysDate,
DATE_ADD(DATE_FORMAT(NOW(),'%Y-%m-%d'),INTERVAL 1 MONTH) AS Add1MonthFromTodaysDate,
DATE_FORMAT(NOW(),'%Y-%m-01') AS FirstDayCurrentMonth ,
LAST_DAY(DATE_FORMAT(NOW(),'%Y-%m-%d')) AS lastDayCurrentMonth,
DATE_SUB(LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH)),
INTERVAL DAY(LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH)))-1 DAY) AS FirstOfNextMont007,
LAST_DAY(DATE_SUB(NOW(), INTERVAL 1 MONTH)) AS lastOfpREMonth,
DATE_SUB(LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH)),
INTERVAL DAY(LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH)))-1 DAY) AS FirstOfNextMonth,
LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH)) AS lastOfNextMonth
【讨论】:
更短的查询:
SELECT
ADDDATE(LAST_DAY(NOW()), 1) AS firstOfNextMonth,
LAST_DAY(DATE_ADD(NOW(), INTERVAL 1 MONTH)) AS lastOfNextMonth
【讨论】:
curdate is better 比now 在速度和意图传达方面。此外,+ 在可读性和命令长度方面都优于DATE_ADD。
在 postgresql 中你有完美的日期截断函数。
对于 MySQL,我发现了一个讨论 here 可能会提供一些想法。
【讨论】:
select Convert(varchar(10),DateAdd(Day, 1, getdate() - Day(getdate()) + 1) -1,105)
select Convert(varchar(10),getdate(),105)
select year(getdate())
【讨论】:
SELECT DATE_ADD(LAST_DAY('2020-12-14'),INTERVAL 1 DAY) AS 'FIRST DAY OF NEXT MONTH';
+----------------------------+
| FIRST DAY OF NEXT MONTH |
+----------------------------+
| 2021-01-01 |
+----------------------------+
1 row in set (1.06 sec)
SELECT DATE_ADD(LAST_DAY(NOW()),INTERVAL 1 MONTH) AS 'LAST DAY OF NEXT MONTH';
+------------------------+
| LAST DAY OF NEXT MONTH |
+------------------------+
| 2020-09-30 |
+------------------------+
1 row in set (0.51 sec)
【讨论】: