You need to enable JavaScript to run this app. SQL统计两个日期之间完整月数的实现方法
优惠活动
大模型
产品
解决方案
定价
更多

SQL统计两个日期之间完整月数的实现方法

问题根因

原代码使用的DATEDIFF(mm, 起始日期, 结束日期),计算逻辑仅比对两个日期所属的月份刻度差,不校验实际间隔是否满足完整月份周期:只要两个日期跨过自然月边界,就会累加月份计数,因此才会出现2021-03-03到2021-05-02被统计为2个月的偏差。
本次需求的核心统计规则为:仅当结束日期到达起始日期对应偏移整月的同一天时,才计入完整月份。按该规则,2021-03-03起始的周期,需到2021-04-03才算满1个月,到2021-05-03才算满2个月;2021-05-02距离满2个月还差1天,因此最终应计数为1。

实现方案

适配当前规则的最简写法

通过比对两个日期的「日」字段,判断最后一个未完成的月份是否需要扣除:

declare @startdate date='2021-03-03';
declare @enddate date='2021-05-02';

select 
    datediff(mm,@startdate,@enddate)
    -- 若结束日期的「日」早于起始日期的「日」,说明最后一个整月未凑齐,扣除计数
    - case when day(@enddate) < day(@startdate) then 1 else 0 end
as full_month_count;

上述代码的返回结果为1,完全匹配预期。

校验用例

  • start=2021-03-03,end=2021-04-03 → 返回1(刚好满1个完整月)
  • start=2021-03-03,end=2021-04-02 → 返回0(距满1个月还差1天,不计数)
  • start=2021-03-03,end=2021-05-03 → 返回2(刚好满2个完整月)
  • 示例场景start=2021-03-03,end=2021-05-02 → 返回1

兼容月底边界的通用写法

如果业务中存在起始日为月底(比如1月31日)、后续月份无对应同日的场景(比如2月没有31日),纯对比DAY()的写法会出现统计偏差,可改用日期偏移校验的逻辑自动适配月底场景:

declare @startdate date='2021-01-31';
declare @enddate date='2021-02-28';

select
    case
        -- 若结束日期大于等于「起始日期偏移N个月的对齐日期」,则N为最终计数
        when @enddate >= dateadd(mm, datediff(mm, @startdate, @enddate), @startdate)
        then datediff(mm, @startdate, @enddate)
        -- 否则扣除1个月的计数
        else datediff(mm, @startdate, @enddate) - 1
    end as full_month_count;

该写法会自动适配SQL中DATEADD的日期溢出逻辑:比如2021-01-31偏移1个月时,会自动返回2021-02-28(2月最后一天),因此2021-02-28会被判定为刚好满1个完整月,符合常规业务统计习惯。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 01:24:05