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

无需查找表生成近12个月及天数的SQL方案咨询

你的递归CTE方案完全可行,我帮你调整来满足天数需求

首先说结论:你贴的这段递归CTE写法是SQL Server里生成连续序列的经典操作,完全兼容所有支持递归CTE的SQL Server版本(从2005年的版本开始,覆盖了几乎所有在用的环境),完美符合你「不用查找表」的要求。不过原代码只返回了月份缩写,我帮你修改成包含对应天数的版本,顺便拆解下R(N)到底是啥意思。

修改后的完整代码(满足近12个月+对应天数)

WITH R(N) AS (
    SELECT 0 
    UNION ALL 
    SELECT N + 1 
    FROM R 
    WHERE N < 11 -- 生成0到11共12个数字,对应近12个月
)
SELECT 
    -- 月份缩写(比如Jan、Feb)
    LEFT(DATENAME(MONTH, DATEADD(MONTH, -N, GETDATE())), 3) AS month_abbr,
    -- 完整月份名称(可选)
    DATENAME(MONTH, DATEADD(MONTH, -N, GETDATE())) AS month_full,
    -- 年份(避免跨年混淆)
    YEAR(DATEADD(MONTH, -N, GETDATE())) AS year,
    -- 当月天数
    DAY(EOMONTH(DATEADD(MONTH, -N, GETDATE()))) AS days_in_month
FROM R
-- 按年份和月份排序,结果更直观
ORDER BY year, DATEPART(MONTH, DATEADD(MONTH, -N, GETDATE()))

如果需要兼容SQL Server 2008及更早版本(这些版本没有EOMONTH函数),把days_in_month的计算改成下面的写法即可:

DAY(DATEADD(DAY, -1, DATEADD(MONTH, 1, DATEADD(DAY, 1 - DAY(GETDATE()), GETDATE())))) AS days_in_month

关于R(N)的含义拆解

这个R(N)是一个递归公共表表达式(CTE),拆分来看:

  • R是这个CTE的自定义名称,N是它里面唯一的列名——你也可以改成别的名字比如Seq(Num),只是社区习惯上用R(N)来指代这类递归序列。
  • 第一行SELECT 0是锚点成员:这是递归的起点,生成第一行数据,N=0对应「当前月份」(因为DATEADD(MONTH, -0, GETDATE())就是当前月)。
  • 第二部分SELECT N + 1 FROM R WHERE N < 11是递归成员:它会反复从R里读取上一次生成的N值,加1后生成新行,直到N不满足<11的条件。这样就生成了0,1,2,...,11这12个连续整数,正好对应「当前月往前推0到11个月」的近12个月范围。

这种递归CTE的好处就是完全动态生成序列,不需要提前创建任何表,完美适配你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:32:00