sql server 中怎么自定义分割月功能,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

1、为何出现自定义分割月的需求

今天梳理一个平台的所有函数时,发现了一个自定义分割月函数,也就是指定分割月的开始日索引值(可以从1-31闭区间内的任何一个值)来获取指定日期所对应的分割月数值。这个函数当时是为了解决业务部门获取非标准月(标准月就是从每个月的第一天到最后一天组成一个完成的标准月份)的统计汇总数据的。例如:如果指定分割月的开始日索引值为5则表示某个月的5号到下个月的4号之间作为一个完整的分割月;同样地如果指定分割月的开始日索引值为1则表示标准月等等。

我仔细梳理了这个函数进行了重构简化以及扩展,该自定义分割月函数的实现区别之前写的SQL Server时间粒度系列----第3节旬、月时间粒度详解文章中将一个整数值和月份日期相互转换功能,这个是按照标准月来实现的,虽然思路大致相同,但是并没有针对之前的月份日期和整数值转换函数对来进行扩展而是独立开发新的功能函数。也是为了尽量做到函数功能职责单一性、稳定性、可维护性以及可扩展性。

2、sql server实现自定义分割月功能

自定义分割月功能函数包括两个标量函数:ufn_SegMonths和ufn_SegMonth3Date。ufn_SegMonths获取指定的日期在自定义分割月对应的分割月数值;ufn_SegMonth3Date获取指定一个分割月数值赌对应的月份日期。

sql server 版本的实现T-SQL代码如下:

IFOBJECT_ID(N'[dbo].[ufn_SegMonths]','FN')ISNOTNULLBEGINDROPFUNCTION[dbo].[ufn_SegMonths];ENDGO--==================================--功能:根据自定义月开始索引值获取指定日期所在的自定义月数。--说明:自定义分割月数=年整数值*100+当前所在分割月值。--环境:SQLServer2005+。--调用:SET@intSegMonths=dbo.fn_SegMonths('2008-01-14',15)。--创建:XXXX-XX-XXXX:XX-XX:XXXXX创建函数实现。--修改:XXXX-XX-XXXX:XX-XX:XXXXXXXXXXXXX。--==================================CREATEFUNCTION[dbo].[ufn_SegMonths](@dtmDateASDATETIME--日期,@tntSegStartIndexOfMonthASINT=15--自定义分割月开始索引值(1-31))RETURNSINTASBEGINIF(@tntSegStartIndexOfMonth=0OR@tntSegStartIndexOfMonth>=32)BEGINSET@tntSegStartIndexOfMonth=15;ENDDECLARE@intYearsASINT,@tntMonthASTINYINT,@sntDayASSMALLINT;SELECT@intYears=DATEDIFF(YEAR,'1900-01-01',@dtmDate),@tntMonth=DATEPART(MONTH,@dtmDate),@sntDay=DATEPART(DAY,@dtmDate);IF(@sntDay>=@tntSegStartIndexOfMonth)BEGINSET@tntMonth=@tntMonth+1;ENDIF(@tntMonth>12)BEGINSELECT@intYears=@intYears+1,@tntMonth=@tntMonth-12;ENDRETURN@intYears*100+@tntMonth;ENDGOIFOBJECT_ID(N'[dbo].[ufn_SegMonths2Date]','FN')ISNOTNULLBEGINDROPFUNCTION[dbo].[ufn_SegMonths2Date];ENDGO--==================================--功能:获取自定义分割月数对应的自定义分割月日期。--说明:自定义分割月日期=自定义分割月数/100对应的年整数日期“组合”当前所在分割月值。--环境:SQLServer2005+。--调用:SET@dtmSegMonthDate=dbo.fn_SegMonths2Date(11602)。--创建:XXXX-XX-XXXX:XX-XX:XXXXX创建函数实现。--修改:XXXX-XX-XXXX:XX-XX:XXXXXXXXXXXXX。;--==================================CREATEFUNCTION[dbo].[ufn_SegMonths2Date](@intSegMonthsASINT--自定义分割月数)RETURNSDATETIMEASBEGINDECLARE@dtmDefaultBasedateASDATETIME;SET@dtmDefaultBasedate='1900-01-01';IF((@intSegMonthsISNULL)OR(@intSegMonths<=0))BEGINRETURN@dtmDefaultBasedate;ENDDECLARE@intYearsASINT,@intMonthASINT;SELECT@intYears=@intSegMonths/100,@intMonth=@intSegMonths%100;RETURNDATEADD(MONTH,@intMonth-1,DATEADD(YEAR,@intYears,@dtmDefaultBasedate));ENDGO

3、测试验证效果

针对以上简单的测试代码如下:

DECLARE@dtmStartDateASDATETIME,@dtmEndDateASDATETIME;SELECT@dtmStartDate='2000-01-01',@dtmEndDate='2016-12-31';SELECT[T1].*,[dbo].[ufn_SegMonths2Date]([T1].[SegMonths])ASSegMonthDateFROM(SELECT[T].[CDate],[dbo].[ufn_SegMonths]([T].[CDate],28)ASSegMonthsFROM(SELECTDATEADD(DAY,[Num],@dtmStartDate)ASCDateFROM[dbo].[ufn_GetNums](0,DATEDIFF(DAY,@dtmStartDate,@dtmEndDate)))ASTWHERE[T].[CDate]BETWEEN'2014-12-01'AND'2016-03-31')AST1WHEREDATEPART(DAY,[T1].[CDate])>=27GO

看完上述内容,你们掌握sql server 中怎么自定义分割月功能的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!