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

如何正确获取指定日期当月周数(周一为周起始,SQL结果不符)

解决按周一为起始计算当月周数的SQL问题

问题说明

  • 需求:计算指定日期在当月的周数,每周以周一为起始日
  • 示例:日期2023-04-28预期返回周数为4,但原有SQL代码返回5,结果不符合预期

原有错误代码

DECLARE @DATE DATETIME
SET @DATE = '20230428'

SELECT DATEPART(WEEK, @DATE)  
     - DATEPART(WEEK, DATEADD(MM, DATEDIFF(MM,0,@DATE), 0)) 
     + 1 AS WEEK_OF_MONTH

错误原因

原有代码依赖DATEPART(WEEK)的差值计算,但该函数存在两个核心问题:

  1. 它计算的是当年的周数,当月份第一天所在周跨月时,差值会包含上个月的周数,导致结果偏大;
  2. 周起始日受服务器SET DATEFIRST配置影响,默认可能以周日为起始,和需求的周一起始规则不匹配。

以2023年4月为例:4月1日是周六,DATEPART(WEEK)将其算作当年第14周,4月28日是当年第18周,差值计算18-14+1=5,和预期的4不符。

解决方案

通过明确指定周一为周起始日,同时基于当月第一个周一为基准计算周数,确保结果符合需求:

DECLARE @DATE DATETIME
SET @DATE = '20230428'
SET DATEFIRST 1; -- 明确设置周一为每周的起始日

-- 获取当月第一天
DECLARE @FirstDayOfMonth DATETIME = DATEADD(MONTH, DATEDIFF(MONTH, 0, @DATE), 0);
-- 计算当月的第一个周一
DECLARE @FirstMondayOfMonth DATETIME = DATEADD(
    DAY, 
    (7 - DATEPART(WEEKDAY, @FirstDayOfMonth) + 1) % 7, 
    @FirstDayOfMonth
);

-- 计算目标日期的当月周数
SELECT 
    CASE 
        WHEN @DATE < @FirstMondayOfMonth THEN 1
        ELSE DATEDIFF(WEEK, @FirstMondayOfMonth, @DATE) + 1
    END AS WEEK_OF_MONTH;

测试验证

  • 输入2023-04-28时,返回结果为4,符合预期;
  • 输入2023-04-01(周六),返回1;
  • 输入2023-04-03(周一),返回1;
  • 输入2023-04-30(周日),返回4。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 03:29:54