如何在SQL递归查询中展示每月最后一天而非第一天
如何在SQL递归查询中展示每月最后一天而非第一天
没问题!我来帮你调整这个查询,让它输出每个月的最后一天,并且格式化为你要的MM-dd-yyyy样式。
你的原查询是通过递归生成每月第一天,我们只需要修改日期生成的逻辑,再加上日期格式化处理就能实现需求。下面分两种场景给出解决方案:
方法一:用EOMONTH函数(SQL Server 2012及以上版本推荐)
EOMONTH是SQL Server 2012新增的函数,可以直接返回指定日期所在月份的最后一天,用法非常简洁直观。修改后的代码如下:
DECLARE @StartDateTime DATETIME DECLARE @EndDateTime DATETIME SET @StartDateTime = '2015-01-01' SET @EndDateTime = '2016-01-12'; WITH DateRange(DateData) AS ( -- 先获取起始日期所在月份的最后一天 SELECT EOMONTH(@StartDateTime) as Date UNION ALL -- 递归获取下一个月的最后一天 SELECT EOMONTH(DATEADD(m,1,DateData)) FROM DateRange -- 调整判断条件:当前最后一天小于结束日期所在月份的最后一天,避免多生成超出范围的日期 WHERE DateData < EOMONTH(@EndDateTime) ) -- 格式化日期为MM-dd-yyyy样式 SELECT FORMAT(DateData, 'MM-dd-yyyy') AS LastDayOfMonth FROM DateRange OPTION (MAXRECURSION 0)
方法二:兼容旧版本SQL Server(2012之前)
如果你的SQL Server版本不支持EOMONTH,可以通过DATEADD的组合计算来获取当月最后一天:当月第一天加一个月后再减一天,就是当月的最后一天。修改后的代码如下:
DECLARE @StartDateTime DATETIME DECLARE @EndDateTime DATETIME SET @StartDateTime = '2015-01-01' SET @EndDateTime = '2016-01-12'; WITH DateRange(DateData) AS ( -- 计算起始日期所在月份的最后一天:先取当月第一天,加一个月,再减一天 SELECT DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, @StartDateTime) + 1, 0)) as Date UNION ALL -- 递归获取下一个月的最后一天 SELECT DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, DateData) + 2, 0)) FROM DateRange -- 判断当前最后一天小于结束日期所在月份的最后一天 WHERE DateData < DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, @EndDateTime) + 1, 0)) ) -- 用CONVERT+REPLACE格式化日期为MM-dd-yyyy SELECT REPLACE(CONVERT(varchar, DateData, 101), '/', '-') AS LastDayOfMonth FROM DateRange OPTION (MAXRECURSION 0)
两种方法的核心逻辑都是把递归生成的「每月第一天」替换成「每月最后一天」,再通过格式化函数把日期转成你需要的样式。如果用FORMAT函数,注意确保SQL Server的语言设置正常;如果用CONVERT+REPLACE,则兼容性更好。
备注:内容来源于stack exchange,提问作者Si8
相关产品推荐
相关产品推荐

