最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

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

来源:动视网 责编:小采 时间:2020-11-09 07:00:55
文档

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

sqlserver自定义分割月功能详解及实现代码:在最近的项目开发过程中,遇到了Sql server自动分割月的功能需求,这里在网上整理下资料. 1、为何出现自定义分割月的需求 今天梳理一个平台的所有函数时,发现了一个自定义分割月函数,也就是指定分割月的开始日索引值(可以从1-31闭区间内的任何一个值)来
推荐度:
导读sqlserver自定义分割月功能详解及实现代码:在最近的项目开发过程中,遇到了Sql server自动分割月的功能需求,这里在网上整理下资料. 1、为何出现自定义分割月的需求 今天梳理一个平台的所有函数时,发现了一个自定义分割月函数,也就是指定分割月的开始日索引值(可以从1-31闭区间内的任何一个值)来


在最近的项目开发过程中,遇到了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数字辅助表的实现这边文章的内联表值函数ufn_GetNums。

 4、总结语

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

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

您可能感兴趣的文章:

  • SqlServer中如何解决session阻塞问题
  • SqlServer 英文单词全字匹配详解及实现代码
  • SqlServer编写数据库表的操作方式(建库、建表、修改语句)
  • C#访问SQLServer增删改查代码实例
  • SqlServer查询和Kill进程死锁的语句
  • 获取SqlServer存储过程定义的三种方法
  • SQLServer主键和唯一约束的区别
  • SqlServer存储过程实现及拼接sql的注意点
  • win2008 r2 服务器php+mysql+sqlserver2008运行环境配置(从安装、优化、安全等)
  • SQLSERVER简单创建DBLINK操作远程服务器数据库的方法
  • SqlServer2008误操作数据(delete或者update)后恢复数据的方法
  • 文档

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

    sqlserver自定义分割月功能详解及实现代码:在最近的项目开发过程中,遇到了Sql server自动分割月的功能需求,这里在网上整理下资料. 1、为何出现自定义分割月的需求 今天梳理一个平台的所有函数时,发现了一个自定义分割月函数,也就是指定分割月的开始日索引值(可以从1-31闭区间内的任何一个值)来
    推荐度:
    标签: 介绍 自定义 实现
    • 热门焦点

    最新推荐

    猜你喜欢

    热门推荐

    专题
    Top