You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SQL中获取两个日期之间的月份编号

在SQL中获取两个日期之间的月份编号

根据不同的SQL数据库,实现方式略有差异,核心逻辑是忽略日期中的日部分,仅基于年月生成连续的月份编号,以下是主流数据库的解决方案:

SQL Server

使用递归CTE生成连续的月份序列,再格式化为两位数字的编号:

DECLARE @StartDate DATE = '2023-01-04', @EndDate DATE = '2023-05-04';

WITH MonthSeries AS (
    SELECT 
        DATEFROMPARTS(YEAR(@StartDate), MONTH(@StartDate), 1) AS MonthStart
    UNION ALL
    SELECT 
        DATEADD(MONTH, 1, MonthStart)
    FROM MonthSeries
    WHERE MonthStart < DATEFROMPARTS(YEAR(@EndDate), MONTH(@EndDate), 1)
)
SELECT FORMAT(MonthStart, 'MM') AS MonthNumber
FROM MonthSeries;

说明

  1. 用DATEFROMPARTS把起始/结束日期转为当月第一天,彻底忽略具体日的影响
  2. 递归CTE生成从起始月到结束月的所有月份第一天
  3. 用FORMAT函数将月份格式化为两位数字的编号

MySQL(8.0+)

通过递归CTE实现连续月份生成:

SET @StartDate = '2023-01-04', @EndDate = '2023-05-04';

WITH MonthSeries AS (
    SELECT 
        STR_TO_DATE(CONCAT(YEAR(@StartDate), '-', MONTH(@StartDate), '-01'), '%Y-%m-%d') AS MonthStart
    UNION ALL
    SELECT 
        DATE_ADD(MonthStart, INTERVAL 1 MONTH)
    FROM MonthSeries
    WHERE MonthStart < STR_TO_DATE(CONCAT(YEAR(@EndDate), '-', MONTH(@EndDate), '-01'), '%Y-%m-%d')
)
SELECT DATE_FORMAT(MonthStart, '%m') AS MonthNumber
FROM MonthSeries;

说明

  1. 通过STR_TO_DATE和CONCAT构造当月第一天,消除日部分的干扰
  2. 递归生成连续的月份区间
  3. 用DATE_FORMAT输出两位格式的月份编号

PostgreSQL

利用generate_series函数直接生成月份序列:

WITH params AS (
    SELECT 
        DATE_TRUNC('month', '2023-01-04'::DATE) AS start_month,
        DATE_TRUNC('month', '2023-05-04'::DATE) AS end_month
)
SELECT TO_CHAR(generate_series(start_month, end_month, '1 month'::interval), 'MM') AS MonthNumber
FROM params;

说明

  1. DATE_TRUNC('month', ...)将日期截断到当月第一天,忽略日部分
  2. generate_series直接生成从起始月到结束月的连续月份区间
  3. TO_CHAR将月份格式化为两位数字

跨年度场景适配

如果日期范围跨年度,比如2023-11-15到2024-02-20,上述代码会自动输出11、12、01、02,无需额外调整。

内容的提问来源于stack exchange,提问作者malcolm richard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 15:55:01