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

如何使用SQL展示指定起止日期范围内的所有月份?

生成起止日期之间的所有月份(SQL实现)

根据你的需求,以下是不同SQL数据库的实现方案,生成起止日期之间的所有月份并格式化为Mon-YYYY样式:

通用递归CTE方案(支持MySQL 8.0+、PostgreSQL、SQL Server等)

递归CTE是最灵活的方式,适用于大多数现代数据库:

MySQL 8.0+ / MariaDB 10.2+

WITH RECURSIVE month_range AS (
    -- 初始化:获取起始日期所在月份的第一天
    SELECT DATE_FORMAT(start_date, '%Y-%m-01') AS month_start
    FROM (
        -- 替换为你的起止日期,格式为DD-MM-YYYY
        SELECT STR_TO_DATE('12-09-2022', '%d-%m-%Y') AS start_date,
               STR_TO_DATE('05-05-2023', '%d-%m-%Y') AS end_date
    ) AS dates
    UNION ALL
    -- 递归:每月加1个月
    SELECT DATE_ADD(month_start, INTERVAL 1 MONTH)
    FROM month_range
    -- 终止条件:不超过结束日期所在月份的第一天
    WHERE month_start <= (SELECT DATE_FORMAT(end_date, '%Y-%m-01') FROM dates)
)
-- 格式化输出为缩写月份+年份
SELECT DATE_FORMAT(month_start, '%b-%Y') AS month_year
FROM month_range;

PostgreSQL

WITH RECURSIVE month_range AS (
    -- 初始化:获取起始日期所在月份的起始时间
    SELECT date_trunc('month', start_date)::DATE AS month_start
    FROM (
        -- 替换为你的起止日期,格式为DD-MM-YYYY
        SELECT TO_DATE('12-09-2022', 'DD-MM-YYYY') AS start_date,
               TO_DATE('05-05-2023', 'DD-MM-YYYY') AS end_date
    ) AS dates
    UNION ALL
    -- 递归:每月加1个月
    SELECT (month_start + INTERVAL '1 month')::DATE
    FROM month_range
    -- 终止条件:不超过结束日期所在月份的起始时间
    WHERE month_start <= date_trunc('month', (SELECT end_date FROM dates))
)
-- 格式化输出为缩写月份+年份
SELECT TO_CHAR(month_start, 'Mon-YYYY') AS month_year
FROM month_range;

SQL Server

WITH month_range AS (
    -- 初始化:获取起始日期所在月份的第一天
    SELECT DATEFROMPARTS(YEAR(start_date), MONTH(start_date), 1) AS month_start
    FROM (
        -- 替换为你的起止日期,格式为DD-MM-YYYY(105对应该格式)
        SELECT CONVERT(DATE, '12-09-2022', 105) AS start_date,
               CONVERT(DATE, '05-05-2023', 105) AS end_date
    ) AS dates
    UNION ALL
    -- 递归:每月加1个月
    SELECT DATEADD(MONTH, 1, month_start)
    FROM month_range
    -- 终止条件:不超过结束日期所在月份的第一天
    WHERE month_start <= DATEFROMPARTS(YEAR((SELECT end_date FROM dates)), MONTH((SELECT end_date FROM dates)), 1)
)
-- 格式化输出为缩写月份+年份
SELECT FORMAT(month_start, 'MMM-yyyy') AS month_year
FROM month_range;

旧版MySQL(无CTE支持)方案

如果使用MySQL 5.x等不支持递归CTE的版本,可以用数字序列表生成:

SELECT DATE_FORMAT(
    DATE_ADD(STR_TO_DATE('12-09-2022', '%d-%m-%Y'), INTERVAL n MONTH), 
    '%b-%Y'
) AS month_year
FROM (
    -- 生成足够多的数字(覆盖最大月份差即可)
    SELECT 0 AS n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
    UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
    UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12
) AS numbers
-- 过滤不超过结束日期的月份
WHERE DATE_ADD(STR_TO_DATE('12-09-2022', '%d-%m-%Y'), INTERVAL n MONTH) <= STR_TO_DATE('05-05-2023', '%d-%m-%Y');

以上方案执行后,都会输出你期望的结果:

Sep-2022
Oct-2022
Nov-2022
Dec-2022
Jan-2023
Feb-2023
Mar-2023
Apr-2023
May-2023

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 12:55:17