本文目录列表:
 
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仓库中使用。国庆一来已经过去一周,原来打算一周一遍的计划还是延期啦,再次严重检讨自己。
 
继续精进SQL Server,继续进发。
 
5、参考清单列表

sql server实现自定义分割月功能的更多相关文章

  1. SQL Server 2012 数据库各个版本功能对比

    作为这篇SQL SERVER 2008数据库各版本功能对比 的姊妹篇,就写点SQL Server 2012 各个版本的区别以及物理以及逻辑上的限制. 个部分来分http://technet.micro ...

  2. ASP.net(C#)利用SQL Server实现注册和登陆功能

    说说我现在吧,楼主现在从事的事IT行业,主攻DotNet技术:当然这次上博客园我也是有备而来,所有再次奉献鄙人拙作,以飨诸位,望诸位不吝赐教. 世界上大多数的工作都是熟练性的工种,编程也不例外,做久了 ...

  3. SQL Server 2005中的CHECKSUM功能

    原文:SQL Server 2005中的CHECKSUM功能 转自此处 页面 checksum 是SQL2005的新功能,提供了一种比残缺页检测强大的机制检测IO方面的损坏.以下是详细描述: 页面 C ...

  4. SQL Server中自定义函数:用指定的分隔符号分割字符串

    微软SQL Server数据库中包含了很多内置的函数,入下图: 它们用于处理日期.数学.元数据.字符串等. 其中最为常用的就是处理字符串,里面包含了CharIndex()等函数,非常方便使用. 但是对 ...

  5. SQL SERVER 2008数据库各版本功能对比

    微软SQL SERVER 2008数据库有6个版本,分别是数据中心版.企业版.标准版.Web版.工作组版.简易版,有时候购买的时候或需要使用某项功能时,需要了解各个版本的区别,功能差异,很多时候,大部 ...

  6. 关于SQL SERVER 2008 R2发布订阅功能

    实现功能:主服务器维护数据的变更,从服务器需要时同步主服务器的数据. 配置:主从服务器均为SQL SERVER 2008 R2. 实现方法: 预备: 1.主从服务器需建立同一账户名及密码的账户(当时我 ...

  7. SQL SERVER 的前世今生--各版本功能对比

    背景 今天举办的 Data Amp 大会上,微软向开发者们强调了 数据如何影响他们的应用和服务 ,顺道还宣布了几个小新闻.这个免费的线上研讨会不仅展示了未来的机器学习远景,还发布了 SQL Serve ...

  8. sql server 将字符串分割成表函数 strsplitetotable

    在sql server里,调用存储过程时,经常需要将数据拼成字符串做为参数调用存储过程,而在储存过程中分割字符串虽然简单但麻烦,封装了该函数,可以将拼串分割成内存表返回,方便使用,返回的表字段从a,b ...

  9. Sql Server-使用Sql Server自带的分词功能实现字段关键词提取(分词能力很低,慎用)

    “创建全文索引 启动服务 在SQL Server配置管理工具中,找到'SQL Full-text Filter Daemon Launcher'服务用本地用户启动. 创建全文目录 打开需要创建全文目录 ...

随机推荐

  1. ruby 访问新浪微博API post方式和get方式

    require 'net/https' require 'uri' def post_api(api, args) uri = URI.parse api http = Net::HTTP.new(u ...

  2. <2048>调查报告心得与体会

    老师这次给我们布置了一个任务,就是让我们写一份属于自己的调查报告,针对这个任务,我们小组的六个人通过积极的讨论,提出了一些关于我们产品的问题,当然这些问题并不是很全面,因为我们是从自己的角度出发,无法 ...

  3. AWS 免费套餐

    AWS 免费套餐 转载自:https://aws.amazon.com/cn/free/?sc_channel=PS&sc_campaign=acquisition_CN&sc_pub ...

  4. c#实现redis客户端(一)

    最近项目使用中要改造redis客户端,看了下文档,总结分享一下. 阅读目录: 协议规范 基础通信 状态命令 set.get命令 管道.事务 总结 协议规范 redis允许客户端以TCP方式连接,默认6 ...

  5. Linux的原子操作与同步机制

    Linux的原子操作与同步机制   .进程1执行完“mov eax, [count]”后,寄存器eax内保存了count的值0.此时,进程2被调度执行,抢占了进程1的CPU的控制权.进程2执行“cou ...

  6. [译]Introducing ASP.NET vNext and MVC 6

    原文:http://www.infoq.com/news/2014/05/ASP.NET-vNext?utm_source=tuicool Part of the ASP.NET vNext init ...

  7. Azure Blob Storage 基本用法 -- Azure Storage 之 Blob

    Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob.Queue.File 和 Table. 笔者在<Azure Table storage ...

  8. appledoc 使用

    1.安装 git clone git://github.com/tomaz/appledoc.git cd ./appledoc sudo sh install-appledoc.sh 2.使用 进入 ...

  9. Android开发学习之路-二维码学习

    这个月装逼有点少了,为什么呢,因为去考软件射鸡师了,快到儿童节了,赶紧写篇博纪念一下逝去的青春,唔,请忽略这句话. 二维码其实有很多种,但是我们常见的微信使用的是一种叫做QRCode的二维码,像下面这 ...

  10. angularjs揭秘

    angularjs揭秘