如何编写SQL查询获取每月最后一个工作日?附自定义函数实现
获取指定月份最后一个工作日的SQL自定义函数
我帮你完善并整理了这个SQL Server自定义函数,用来获取指定月份的最后一个工作日,下面是完整代码和详细的逻辑说明:
完整函数代码
CREATE FUNCTION dbo.ufn_LastBusinessDayOfMonth (@Dt datetime) RETURNS datetime AS BEGIN DECLARE @dt2 datetime DECLARE @dSat int DECLARE @dSun int -- 获取传入日期所在月份的最后一天 SELECT @dt2 = DATEADD(D, -1, DATEADD(m, 1 + DATEDIFF(m, 0, @Dt), 0)) -- 动态确定当前系统中周六、周日对应的DATEPART(dw)值 -- 用已知的周六日期(2018-01-06)获取系统定义的周六编号 SELECT @dSat = DATEPART(dw, '2018-01-06') -- 推导周日的编号,确保在1-7的范围内 SELECT @dSun = (@dSat % 7) + 1 -- 根据月末当天的星期几,调整为最后一个工作日 SELECT @dt2 = ( CASE WHEN DATEPART(dw, @dt2) = @dSun THEN DATEADD(DAY, -2, @dt2) -- 周日则回退到周五 WHEN DATEPART(dw, @dt2) = @dSat THEN DATEADD(DAY, -1, @dt2) -- 周六则回退到周五 ELSE @dt2 -- 工作日直接返回 END ) RETURN @dt2 END
核心逻辑拆解
- 精准获取月末日期:
DATEADD(D, -1, DATEADD(m, 1 + DATEDIFF(m, 0, @Dt), 0))是SQL Server中获取月末的通用写法——先计算传入日期下一月的第一天,再减1天,完美适配不同月份的天数差异,不用手动判断2月、30天/31天的月份。 - 兼容系统星期设置:
DATEPART(dw)返回的星期编号(比如1是周日还是周一)受SQL Server的SET DATEFIRST配置影响,所以这里用已知的周六日期2018-01-06动态获取当前系统的周六编号,再推导周日编号,确保函数在任何星期起始设置下都能正确识别周末。 - 周末自动调整:如果月末当天是周末,就自动回退到最近的工作日:周日回退2天到周五,周六回退1天到周五;如果是工作日则直接返回,保证结果是当月最后一个非周末的日期。
快速使用示例
-- 查询2024年6月的最后一个工作日 SELECT dbo.ufn_LastBusinessDayOfMonth('2024-06-01') AS LastBusinessDayOfJune;
内容的提问来源于stack exchange,提问作者user9530119
相关产品推荐
相关产品推荐

