如何用SQL获取每个月的最后一周日期?
获取每个月最后一周日期的SQL方案
首先明确“最后一周”的常见两种定义,对应不同的SQL实现:
定义1:每个月的最后7天(适配所有月份天数)
这种方法不依赖固定日期数值,通过计算每个日期所在月份的最后一天,自动筛选出最后7天,完美适配28/29/30/31天的月份:
PostgreSQL 版本
SELECT date FROM date_table WHERE date >= (DATE_TRUNC('month', date) + INTERVAL '1 month - 7 days')::DATE AND date <= (DATE_TRUNC('month', date) + INTERVAL '1 month - 1 day')::DATE;
解释:
DATE_TRUNC('month', date)获取当前日期所在月份的第一天(比如2024-02-01)+ INTERVAL '1 month'得到下一个月的第一天(2024-03-01),减7天就是当月倒数第7天(2024-02-22),减1天就是当月最后一天(2024-02-29)- 无需手动调整不同月份的日期范围,就能精准筛选出每个月的最后7天
MySQL 版本
如果使用MySQL,可用LAST_DAY函数简化计算:
SELECT date FROM date_table WHERE date >= DATE_SUB(LAST_DAY(date), INTERVAL 6 DAY) AND date <= LAST_DAY(date);
定义2:每个月的最后一个完整星期(按星期起始日调整)
如果“最后一周”指当月最后一个完整的星期(比如周一到周日,或周日到周六),需要先明确星期的起始日,以下以PostgreSQL为例(ISO周,周一为起始日):
SELECT date FROM date_table -- 获取当月最后一天所在周的周一,往前推6天得到上周日(适配周日起始的完整周) WHERE date >= (DATE_TRUNC('week', (DATE_TRUNC('month', date) + INTERVAL '1 month - 1 day')::DATE) - INTERVAL '6 days')::DATE AND date <= (DATE_TRUNC('month', date) + INTERVAL '1 month - 1 day')::DATE;
若你的星期以周日为起始日,可调整逻辑:先找到当月最后一个周日,再往前推6天得到该周的周一。
替代方案:利用表中已有的year/month字段
如果date_table已存储year(数字型,如2024)和month(数字型,如2)字段,可使用以下方式计算:
PostgreSQL 版本
SELECT date FROM date_table WHERE date >= (DATE_TRUNC('month', MAKE_DATE(year, month, 1)) + INTERVAL '1 month - 7 days')::DATE AND date <= (DATE_TRUNC('month', MAKE_DATE(year, month, 1)) + INTERVAL '1 month - 1 day')::DATE;
你之前方法的问题
你用day_of_month >=22 and day_of_month <31的写法,无法适配不同月份的天数:比如2月最多28/29天,22到28是7天,但31天的月份22到31是10天,不符合“最后一周”的要求;而基于月份最后一天的计算方法,能自动适配所有月份的差异。
内容的提问来源于stack exchange,提问作者coolguy
相关产品推荐
相关产品推荐

