MySQL获取上个月的具体日期



我想选择自上个月20th以来的所有行。

我知道我可以使用SELECT NOW() - INTERVAL 1 MONTH选择一个月前的日期,但我如何设置该月的特定日期?

今天是March 28th,我想选择所有比February 20th新的行。

即使我可以直接设置日期,如果查询的日期是31st,这对二月也不起作用,而是应该选择当月的最后一天。

注意:第20个只是一个示例,该值是在代码的其他地方动态生成的。

一些例子:

Day: 20th each month
Now: March 28th | Query: February 20th
Now: May 28th | Query: April 20th
Day: 31st each month
Now: March 28th | Query: February 28th // we select last day instead of 31st
Now: May 28th | Query: April 30th // we select last day instead of 31st

完整的查询将类似于SELECT * FROM sales WHERE date > SET_DAY(20, NOW() - INTERVAL 1 MONTH)

那么,我可以用什么来代替SET_DAY(也适用于较短的月份(?

一个非常常见的用例是计费周期,您希望从当前计费周期中选择所有数据。

好吧,我相信这解决了的问题

select now()
- interval 1 month
- interval(
day(now())
- least(
20,
day(last_day(now() - interval 1 month))
)
) day

假设您在客户端中有一个参数是目标日期,并且您想在sql中验证它(确保您在上个月内找到一天(,而不是在客户端中,我会这样做:

least(
date(date_format(current_date - interval 1 month, '%Y-%m-01')) + interval ? - 1 day,
date(date_format(current_date, '%Y-%m-01')) - interval 1 day
)

注意:current_date将是连接时区中的当前日期,由客户端控制;如果我知道一天要在哪个时区,我更喜欢明确,比如:

date(convert_tz(utc_timestamp(), '+00:00', 'America/Los_Angeles'))

而不仅仅是current_date(两个位置(。

我刚刚意识到我的问题并没有包括所有的案例。如果最后一个计费日期在本月内,则应计算本月的20日(而不是前一个(。

根据@ysth的回答,我添加了一个IF来选择本月的20号(如果我们通过了它(,否则是上个月的:

IF(DAY(current_date) >= 20, 
date(date_format(current_date, '%Y-%m-01')) + interval 20 - 1 day,
least(
date(date_format(current_date - interval 1 month, '%Y-%m-01')) + interval 20 - 1 day,
date(date_format(current_date, '%Y-%m-01')) - interval 1 day
)
);

最新更新