数据库教程:sql server 自定义分割月功能详解及实现代码

在最近的项目开发过程中,遇到了sql server自动分割月的功能需求,这里在网上整理下资料.       1

在最近的项目开发过程中,遇到了sql server自动分割月的功能需求,这里在网上整理下资料.      

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

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

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

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

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

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

  if object_id(n'[dbo].[ufn_segmonths]', 'fn') is not null  begin    drop function [dbo].[ufn_segmonths];  end  go     --==================================  -- 功能:根据自定义月开始索引值获取指定日期所在的自定义月数。  -- 说明:自定义分割月数 = 年整数值*100 + 当前所在分割月值。  -- 环境:sql server 2005+。  -- 调用:set @intsegmonths = dbo.fn_segmonths('2008-01-14', 15)。  -- 创建:xxxx-xx-xx xx:xx-xx:xx xxx 创建函数实现。  -- 修改:xxxx-xx-xx xx:xx-xx:xx xxx xxxxxxxx。  --==================================  create function [dbo].[ufn_segmonths]  (     @dtmdate as datetime            -- 日期    ,@tntsegstartindexofmonth as int = 15    -- 自定义分割月开始索引值(1-31)  )  returns int  as  begin      if (@tntsegstartindexofmonth = 0 or @tntsegstartindexofmonth >= 32)    begin      set @tntsegstartindexofmonth = 15;    end       declare       @intyears as int      ,@tntmonth as tinyint      ,@sntday as smallint;        select       @intyears = datediff(year, '1900-01-01', @dtmdate)      ,@tntmonth = datepart(month, @dtmdate)      ,@sntday = datepart(day, @dtmdate);       if (@sntday >= @tntsegstartindexofmonth)    begin      set @tntmonth = @tntmonth + 1;      end       if (@tntmonth > 12)    begin      select         @intyears = @intyears + 1        ,@tntmonth = @tntmonth - 12;    end       return @intyears * 100 + @tntmonth;  end  go     if object_id(n'[dbo].[ufn_segmonths2date]', 'fn') is not null  begin    drop function [dbo].[ufn_segmonths2date];  end  go     --==================================  -- 功能:获取自定义分割月数对应的自定义分割月日期。  -- 说明:自定义分割月日期 = 自定义分割月数/100对应的年整数日期“组合”当前所在分割月值。  -- 环境:sql server 2005+。  -- 调用:set @dtmsegmonthdate = dbo.fn_segmonths2date(11602)。  -- 创建:xxxx-xx-xx xx:xx-xx:xx xxx 创建函数实现。  -- 修改:xxxx-xx-xx xx:xx-xx:xx xxx xxxxxxxx。;  --==================================  create function [dbo].[ufn_segmonths2date]  (     @intsegmonths as int            -- 自定义分割月数  )  returns datetime  as  begin        declare @dtmdefaultbasedate as datetime;    set @dtmdefaultbasedate = '1900-01-01';       if ((@intsegmonths is null) or (@intsegmonths <= 0))    begin      return @dtmdefaultbasedate;    end       declare       @intyears as int      ,@intmonth as int;      select       @intyears = @intsegmonths / 100      ,@intmonth = @intsegmonths % 100;         return dateadd(month, @intmonth - 1, dateadd(year, @intyears, @dtmdefaultbasedate));  end  go       

3、测试验证效果

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

  declare     @dtmstartdate as datetime    ,@dtmenddate as datetime;     select     @dtmstartdate = '2000-01-01'    ,@dtmenddate = '2016-12-31';     select    [t1].*    ,[dbo].[ufn_segmonths2date]([t1].[segmonths]) as segmonthdate  from (    select      [t].[cdate]      ,[dbo].[ufn_segmonths]([t].[cdate], 28) as segmonths       from (      select        dateadd(day, [num], @dtmstartdate) as cdate      from        [dbo].[ufn_getnums](0, datediff(day, @dtmstartdate, @dtmenddate))    ) as t    where [t].[cdate] between '2014-12-01' and '2016-03-31'  ) as t1  where datepart(day, [t1].[cdate]) >= 27  go  

效果截图如下:

sql server 自定义分割月功能详解及实现代码

 注意:以上测试代码使用了sql server数字辅助表的实现这边文章的内联表值函数ufn_getnums。

 4、总结语

这次是梳理平台的功能性函数所进行的重构简化以及扩展的实现。尽量将日期有关的功能函数梳理出来,便于直接在sql server用户数据库中来使用, 也便于bi仓库中使用。国庆一来已经过去一周,原来打算一周一遍的计划还是延期啦,再次严重检讨自己。

  感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

需要了解更多数据库技术:sql server 自定义分割月功能详解及实现代码,都可以关注数据库技术分享栏目—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/dtteaching/613230.html

(0)
上一篇 2021年5月19日
下一篇 2021年5月19日

精彩推荐