原文:T-SQL: 17 个与日期时间相关的自定义函数(UDF),周日作为周的最后一天,均不受 @@DateFirst、语言版本影响!

CSDN 的 Blog 太滥了!无时不刻地在坏!

开始抢救性搬家 ... ... 到这里重建家园

/*

T-SQL: 17 个与日期时间相关的自定义函数(UDF),周日作为周的最后一天,均不受 @@DateFirst、语言版本影响

都是从老文章里收集或提炼出来的!

提示:

(@@Datefirst + datepart(weekday,@Date)) % 7 判断周几是最保险的! 与 @@DateFirst 无关,与语言版本无关

@@DateFirst 可能会导致 datepart(weekday,@Date) 不一样!

无论 @@DateFirst 等于几,无论是什么语言版本的 SQL Server 下面永远恒成立!

(@@Datefirst + datepart(weekday,@Date))%7 : 2、3、4、5、6、0、1 分别代表 周一 到 周日

-- */



create function udf_GetAge(@StartDate datetime,@EndDate datetime)

returns integer

-- 返回精确年龄 select dbo.udf_GetAge('1949-10-01',getdate())

begin

return datediff(year,@StartDate,@EndDate)

       - case when datediff(day,dateadd(year,datediff(year,@StartDate,@EndDate),@StartDate),@EndDate) >= 0

                   then 0

              else

                   1

         end

end

go

create function udf_DaysOfYearByDate(@Date datetime)

returns integer

-- 返回年的天数 可判断 平(365)、润(366) 年

begin

return datediff(day,dateadd(year,datediff(year,0,@Date),0),dateadd(year,datediff(year,0,@Date) + 1,0))

end

go

create function udf_DaysOfYear(@Year integer)

returns integer

-- 返回年的天数 可判断 平(365)、润(366) 年

begin

return datediff(day,dateadd(year,@year - year(0),0),dateadd(year,@year - year(0) + 1,0))

end

go

create function udf_HalfDay(@Date datetime)

returns datetime

-- 返回 @Date 是 上午 返回 @Date 的零点,@Date 是 下午 返回 @Date 的十二点

begin

return case when datepart(hour,@Date) < 12

                 then dateadd(day,datediff(day,0,@Date),0) --上午归到 零点

            else

                 dateadd(hour,12,dateadd(day,datediff(day,0,@Date),0)) --下午归到 十二点

       end

end

go

create function udf_WeekDiff(@StartDate datetime,@EndDate datetime)

returns integer

-- 返回 [@StartDate , @EndDate] 之间周数 周日是当周的最后一天

begin

return datediff(week,@StartDate,@EndDate) -- + 1

       + case when (@@Datefirst + datepart(weekday,@StartDate)) % 7 = 1

                   then 1

              else

                   0

         end

       - case when (@@Datefirst + datepart(weekday,@EndDate)) % 7 = 1

                   then 1

              else 0

         end

end

go

create function udf_WeekOfMonth(@Date datetime)

-- 返回 @Date 是所在月的第几周 周日是当周的最后一天

returns integer

begin

return datediff(week

                ,case when (@@Datefirst + datepart(weekday,dateadd(month,datediff(month,0,@Date),0))) % 7 = 1

                           then dateadd(month,datediff(month,0,@Date),0) - 1

                      else

                           dateadd(month,datediff(month,0,@Date),0)

                      end

                ,case when (@@Datefirst + datepart(weekday,@Date)) % 7 = 1

                           then @Date-1

                      else @Date

                 end

               ) + 1

end

go

create function udf_WeekOfQuarter(@Date datetime)

-- 返回 @Date 是所在季度的第几周 周日是当周的最后一天

returns int

begin

return datediff(week

                ,case when (@@Datefirst + datepart(weekday,dateadd(Quarter,datediff(Quarter,0,@Date),0))) % 7 = 1

                           then dateadd(Quarter,datediff(Quarter,0,@Date),0) - 1

                      else

                           dateadd(Quarter,datediff(Quarter,0,@Date),0)

                 end

                ,case when (@@Datefirst + datepart(weekday,@Date)) % 7 = 1

                           then @Date - 1

                      else

                           @Date

                 end

               ) + 1

end

go

create function udf_WeekOfYear(@Date datetime)

-- 返回 @Date 是所在年的第几周 周日是当周的最后一天

returns int

begin

return datediff(week

                ,case when (@@Datefirst + datepart(weekday,dateadd(day,0,datediff(day,0,dateadd(year,datediff(year,0,@Date),0))))) % 7 = 1

                           then dateadd(day,-1,dateadd(day,0,datediff(day,0,dateadd(year,datediff(year,0,@Date),0))))

                      else

                           dateadd(day,0,datediff(day,0,dateadd(year,datediff(year,0,@Date),0))) --date 所在年的第一天 即: 一月一号

                 end

                ,case when (@@Datefirst + datepart(weekday,@Date)) % 7 = 1

                           then dateadd(day,-1,@Date)

                      else

                           @Date

                 end

               ) + 1

end

go

create function udf_WeekDay(@ int,@Date datetime)

returns datetime

-- 返回 @Date 所在周的其他天 周一 到 周日 也就是映射到 所在周的其他天 周日是当周的最后一天

begin

/*

--周日算作(上一)周的最后一天

 当 @ <= 1 代表将 @Date 映射到 所在周的星期一

 当 @ = 2 代表将 @Date 映射到 所在周的星期二

 当 @ = 3 代表将 @Date 映射到 所在周的星期三

 当 @ = 4 代表将 @Date 映射到 所在周的星期四

 当 @ = 5 代表将 @Date 映射到 所在周的星期五

 当 @ = 6 代表将 @Date 映射到 所在周的星期六

 当 @ >= 7 代表将 @Date 映射到 所在周的星期日

 可用于按周汇总 Group by,均支持跨年跨月数据

*/

return dateadd(day

               ,case when (@@Datefirst + datepart(weekday,@Date)) % 7 = 0 --周六

                          then case when @ between 1 and 6

                                         then @ - 6

                                    else

                                         1

                               end

                     when (@@Datefirst + datepart(weekday,@Date)) % 7 = 1 --周日(七)

                          then case when @ between 1 and 6

                                         then @ - 7

                                    else

                                         0

                               end

                     when (@@Datefirst + datepart(weekday,@Date)) % 7 between 2 and 6 --周一至周五

                          then case when @ between 1 and 6

                                         then @ + 1 - (@@Datefirst + datepart(weekday,@Date)) % 7

                                    else

                                         8 - (@@Datefirst + datepart(weekday,@Date)) % 7

                               end

                end

               ,@Date)

end

go

create function udf_WeekdayDiff(@Weekday integer,@StartDate datetime,@EndDate datetime)

returns integer

-- 返回 [@StartDate , @EndDate] 之间周一 到 周日的个数 周日是当周的最后一天

begin

-- @Weekday: 1: Monday , ... ,7: Sunday

return datediff(week,@StartDate,@EndDate)

       + case when (@@Datefirst + datepart(weekday,@StartDate)) % 7

                   + case when (@@Datefirst + datepart(weekday,@StartDate)) % 7 = 0

                               then 7

                          else

                               0

                     end > @Weekday % 7 + 1

                   then 0

              else 1

         end

       - case when (@@Datefirst + datepart(weekday,@EndDate)) % 7

                   + case when (@@Datefirst + datepart(weekday,@EndDate)) % 7 = 0

                               then 7

                          else 0

                     end >= @Weekday % 7 + 1

                   then

                        0

              else

                   1

         end

/* test:

declare @b datetime

declare @e datetime

set @b = '2004-01-29'

set @e = '2004-09-05'

select @b as BeginDate ,@e as EndDate

,dbo.udf_WeekdayDiff(1,@b,@e) as CountOfMonday

,dbo.udf_WeekdayDiff(2,@b,@e) as CountOfTuesday

,dbo.udf_WeekdayDiff(3,@b,@e) as CountOfWednesday

,dbo.udf_WeekdayDiff(4,@b,@e) as CountOfThursday

,dbo.udf_WeekdayDiff(5,@b,@e) as CountOfFriday

,dbo.udf_WeekdayDiff(6,@b,@e) as CountOfSaturday

,dbo.udf_WeekdayDiff(7,@b,@e) as CountOfSunday

*/

end

go

create function udf_WeekdayID(@Date datetime)

returns integer

-- 返回 @Date 是 Monday 返回 1, ... ,是 Sunday 返回 1

begin

--1: Monday , ... ,7: Sunday

return (@@Datefirst + datepart(weekday,@Date)) % 7

       + case when (@@Datefirst + datepart(weekday,@Date)) % 7 < 2

                   then 6

              else

                   -1

         end

end

go

create function udf_DayOfQuarter(@Date datetime)

-- 返回 @Date 是所在季度的第几天

returns integer

as

begin

/*

declare @date datetime

set @date = '2004-4-1'

--*/

return datediff(day

               ,dateadd(Quarter,datediff(Quarter,0,@Date),0)

               ,@Date

               ) + 1

end

go

create function udf_DaysOfQuarterByDate(@Date datetime)

-- 返回 @Date 所在季度的天数

returns integer

begin

/*

declare @date datetime

set @date = '2004-4-1'

--*/

return datediff(day

               ,dateadd(Quarter,datediff(Quarter,0,@Date),0)

               ,dateadd(Quarter,datediff(Quarter,0,@Date) + 1,0)

               )

end

go

create function udf_NextWorkDate(@Date datetime)

returns datetime

-- 返回 @Date 的下一个工作日

begin

/*

declare @i int

set @i = 3

declare @Date datetime

set @Date = '2005-01-02'

-- */

return case when (@@Datefirst + datepart(weekday,@Date)) % 7 = 6 -- Friday

                 then dateadd(day,3,@Date)

            when (@@Datefirst + datepart(weekday,@Date)) % 7 = 0 -- saturday

                 then dateadd(day,2,@Date)

            else

                 dateadd(day,1,@Date)

       end

end

go

create function udf_PreviousWorkDate(@Date datetime)

returns datetime

-- 返回 @Date 的上一个工作日

begin

/*

declare @i int

set @i = 3

declare @Date datetime

set @Date = '2005-01-02'

-- */

return case when (@@Datefirst + datepart(weekday,@Date)) % 7 = 2 -- Monday

                 then dateadd(day,-3,@Date)

            when (@@Datefirst + datepart(weekday,@Date)) % 7 = 1 -- Sunday

                 then dateadd(day,-2,@Date)

            else

                 dateadd(day,-1,@Date)

       end

end

go

create function udf_WorkDateAdd(@i integer,@Date datetime)

returns datetime

-- 返回 @Date 加上一段 @i 个工作日的新值

begin

declare @ int

set @ = 0

while @ < abs(@i)

begin

   set @Date = case when @i >= 0

                         then --dbo.udf_nextworkdate(@Date)

                              case when (@@Datefirst + datepart(weekday,@Date)) % 7 = 6 -- Friday

                                        then @date + 3 --dateadd(day,3,@Date)

                                   when (@@Datefirst + datepart(weekday,@Date)) % 7 = 0 -- saturday

                                        then  @date + 2 --dateadd(day,2,@Date)

                                   else

                                         @date + 1 --dateadd(day,1,@Date)

                              end

                    else

                         --dbo.udf_previousworkdate(@Date)

                         case when (@@Datefirst + datepart(weekday,@Date)) % 7 = 2 -- Monday

                                   then  @date - 3 --dateadd(day,-3,@Date)

                              when (@@Datefirst + datepart(weekday,@Date)) % 7 = 1 -- Sunday

                                   then  @date - 2  --dateadd(day,-2,@Date)

                              else

                                    @date - 1 --dateadd(day,-1,@Date)

                         end

               end

               set @ = @ + 1

end

return @Date

end

go

create function udf_GetStar (@ datetime)

returns varchar(100)

-- 返回日期所属星座,如果有静态的 星座对照码表 直接在查询中 join 效率相对更高

begin

return

(

--declare @ datetime

--set @ = getdate()

select max(star)

from

(

select '魔羯座' as star,1 as [month],1 as [day]

union all select '水瓶座',1,20

union all select '双鱼座',2,19

union all select '牡羊座',3,21

union all select '金牛座',4,20

union all select '双子座',5,21

union all select '巨蟹座',6,22

union all select '狮子座',7,23

union all select '处女座',8,23

union all select '天秤座',9,23

union all select '天蝎座',10,24

union all select '射手座',11,22

union all select '魔羯座',12,22

) stars

where dateadd(month,[month] - 1,dateadd(year,year(@) - year(0),0)) + [day] - 1 =

(

select max(dateadd(month,[month] - 1,dateadd(year,year(@) - year(0),0)) + [day] - 1)

from (

select '魔羯座' as star,1 as [month],1 as [day]

union all select '水瓶座',1,20

union all select '双鱼座',2,19

union all select '牡羊座',3,21

union all select '金牛座',4,20

union all select '双子座',5,21

union all select '巨蟹座',6,22

union all select '狮子座',7,23

union all select '处女座',8,23

union all select '天秤座',9,23

union all select '天蝎座',10,24

union all select '射手座',11,22

union all select '魔羯座',12,22

) stars

where @ >= dateadd(month,[month] - 1,dateadd(year,year(@) - year(0),0)) + [day] - 1

)

)

end

go

-- 注意这里用 40 足够了,因为每个月至多才 31 天

select a.birthdate,b.star

from employees a

left join

(

select a.*,isnull(b.month,12) as m,isnull(b.day,31) as d

from stars a

left join stars b

on a.month * 40 + a.day < b.month * 40 + b.day

and b.month * 40 + b.day  = (select min(month * 40 + day) from stars where month * 40 + day > a.month * 40 + a.day)

) b

on month(a.birthdate) * 40 + day(a.birthdate) >= b.month * 40 +  b.day

and month(a.birthdate) * 40 + day(a.birthdate) < b.m * 40 +  b.d

select e.birthdate,a.star

from employees e

left join stars a

on month(e.birthdate) * 40 + day(e.birthdate) >= a.month * 40 + a.day

left join stars b

on a.month * 40 + a.day < b.month * 40 + b.day

and b.month * 40 + b.day  = (select min(month * 40 + day) from stars where month * 40 + day > a.month * 40 + a.day)

where month(e.birthdate) * 40 + day(e.birthdate) < isnull(b.month * 40 + b.day,999)

select *

from stars a

left join stars b

on a.month * 40 + a.day < b.month * 40 + b.day

and b.month * 40 + b.day  = (select min(month * 40 + day) from stars where month * 40 + day > a.month * 40 + a.day)

go

--周历

declare @ datetime

set @ = getdate()

select @ +

case when (@@Datefirst + datepart(weekday,@)) % 7 = 0 --周六

          then -5

     when (@@Datefirst + datepart(weekday,@)) % 7 = 1 --周日(七)

          then -6

     when (@@Datefirst + datepart(weekday,@)) % 7 between 2 and 6 --周一至周五

          then 2 - (@@Datefirst + datepart(weekday,@)) % 7

end + N.i

from

(

select 0 as i

union all select 1 union all select 2 union all select 3

union all select 4 union all select 5 union all select 6

union all select 7

) N

//csc noname1.cs

// 装配脑袋 作 C# 计算任意时段内的 之间周一 到 周日的个数 周日是当周的最后一天

using System;

public class Class1

{

 static void Main(string[] args)

 {

  System.Console.WriteLine("Hello World");

  System.DateTime Start = System.DateTime.Parse("2005-3-6");

  System.DateTime End = System.DateTime.Parse("2005-3-7");

  System.Console.WriteLine(WeekdaysIn(DayOfWeek.Monday,Start,End)); //周一

  System.Console.WriteLine(WeekdaysIn(DayOfWeek.Tuesday,Start,End));

  System.Console.WriteLine(WeekdaysIn(DayOfWeek.Wednesday,Start,End));

  System.Console.WriteLine(WeekdaysIn(DayOfWeek.Thursday,Start,End));

  System.Console.WriteLine(WeekdaysIn(DayOfWeek.Friday,Start,End));

  System.Console.WriteLine(WeekdaysIn(DayOfWeek.Saturday,Start,End));

  System.Console.WriteLine(WeekdaysIn(DayOfWeek.Sunday,Start,End)); //周七(日)

  System.Console.ReadLine();

 }

 private static int WeekdaysIn(DayOfWeek Weekday, DateTime StartDate, DateTime EndDate)

 {

  int d = (EndDate - StartDate).Days;

  int w = d / 7;

  int offset = (int) StartDate.DayOfWeek + d % 7;

  if ((int) Weekday < (int) StartDate.DayOfWeek)

  {

   Weekday = (DayOfWeek)((int) Weekday + 7);

  }

  if ((int)Weekday <= offset)

  {

   w ++;

  }

  return w;

 }

}

T-SQL: 17 个与日期时间相关的自定义函数(UDF),周日作为周的最后一天,均不受 @@DateFirst、语言版本影响!的更多相关文章

  1. 大数据学习day29-----spark09-------1. 练习: 统计店铺按月份的销售额和累计到该月的总销售额(SQL, DSL,RDD) 2. 分组topN的实现(row_number(), rank(), dense_rank()方法的区别)3. spark自定义函数-UDF

    1. 练习 数据: (1)需求1:统计有过连续3天以上销售的店铺有哪些,并且计算出连续三天以上的销售额 第一步:将每天的金额求和(同一天可能会有多个订单) SELECT sid,dt,SUM(mone ...

  2. Sql Server中常用的6个自定义函数分享

    转自:http://www.jb51.net/article/56691.htm IF OBJECT_ID('DBO.DISTINCT_STR') IS NOT NULL DROP FUNCTION ...

  3. 自定义函数导致的sql性能问题

    同事说,某某报表跑的很慢,让我调查一下 优化前:该报表整体需要跑4小时以上. sql代码如下 SELECT /*省略多数查询字段*/ REP_FUN_REFCODEVALUE /*自定义函数*/ (P ...

  4. [转载]SQL语句中的日期计算

    1. 本月的第一天SELECT  DATEADD(mm,  DATEDIFF(mm,0,getdate()),  0) 2. 本月的最后一天SELECT  dateadd(ms,-3,DATEADD( ...

  5. jdbc 日期时间相关的类型

    jdbc 日期时间相关的类型 1.sql.Date sql包中的日期类Date是util包中Date类的子类,实际上也是util.Date类的子集.它只处理年月日,而忽略小时和分秒,用以代表SQL的D ...

  6. Java_日期时间相关类

    目录 Date类(java.util.date) Calendar类(java.util.Calendar) SimpleDateFormat类(java.text.SimpleDateFormat) ...

  7. PL/SQL学习笔记之日期时间

    一:PL/SQL时间相关类型 PL/SQL提供两个和日期时间相关的数据类型: 日期时间(Datetime)数据类型 时间间隔类型 二:日期时间类型 datetime数据类型有: DATE TIMEST ...

  8. SQL Fundamentals || Single-Row Functions || 日期函数date functions

    SQL Fundamentals || Oracle SQL语言   SQL Fundamentals: Using Single-Row Functions to Customize Output使 ...

  9. sql server中的日期详解使用(convert)

    转自:http://blog.csdn.net/hehe520347/article/details/48496853 有个字段值例如2012-07-02 00:00:00.000 转化成 2012- ...

随机推荐

  1. celery最佳实践

    作为一个Celery使用重度用户.看到Celery Best Practices这篇文章.不由得菊花一紧. 干脆翻译出来,同一时候也会添加我们项目中celery的实战经验. 至于Celery为何物,看 ...

  2. 网页显示UIWebView(一个)

    1.scalesPageToFit设置为YES,这样web页面会依据屏幕大小进行自己主动缩放. 2.UIWebView的状态监视 //内容读入開始前被调用.将UIWebView,返回no后UIWebV ...

  3. Cookie和Session (转)

    Session和Cookie在网站开发中是用来保存用户与后端服务器的交互状态.它们有各自的缺点和优点.而且,他们的优点和应用场景是对立的.   Cookie 完整地描述:当一个用户通过HTTP访问一个 ...

  4. SSH深度历险记(八) 剖析SSH核心原则+Spring依赖注入的三种方式

           于java发育.一类程序猿必须依靠类的其他方法,它是通常new依赖类的方法,然后调用类的实例,这样的发展问题new良好的班统一管理的例子.spring提出了依赖注入的思想,即依赖类不由程 ...

  5. ftp的port和pasv型号比较

    一个.ftp的port和pasv工作方式        FTP使用2个TCPport,首先是建立一个命令port(控制port),然后再产生一个数据port. 国内非常多教科书都讲ftp使用21命令p ...

  6. 创意HTML5文字特效 类似翻页的效果

    原文:创意HTML5文字特效 类似翻页的效果 之前在网上看到一款比较有新意的HTML5文字特效,文字效果是当鼠标滑过是出现翻开折叠的效果,类似书本翻页.于是我兴致勃勃的点开源码看了一下,发现其实实现也 ...

  7. 使 IIS 6.0 可以在 64 位 Windows 上运行 32 位应用程序 试图加载格式不正确的程序。

    原文 使 IIS 6.0 可以在 64 位 Windows 上运行 32 位应用程序 试图加载格式不正确的程序. win7 64位操作系统上边运行IIS网站应用的时候,提示错误"试图加载格式 ...

  8. 【年终分享】彩票数据预测算法(一):离散型马尔可夫链模型实现【附C#代码】

    原文:[年终分享]彩票数据预测算法(一):离散型马尔可夫链模型实现[附C#代码] 前言:彩票是一个坑,千万不要往里面跳.任何预测彩票的方法都不可能100%,都只能说比你盲目去买要多那么一些机会而已. ...

  9. 解决opengl计算顶点的法线问题

    因为需要的论文,最近开始学习OpenGL.由于刚入门的初学者有这么总会遇到很多问题,. 这些天,好不容易才OpenGL个问题弄明确了. 几点迷惑: 在网上百度.发现非常多求平面法向量的介绍以及程序.后 ...

  10. 探寻宝藏(双向DP)

    题目描述 传说HMH大沙漠中有一个M*N迷宫,里面藏有许多宝物.某天,Dr.Kong找到了迷宫的地图,他发现迷宫内处处有宝物,最珍贵的宝物就藏在右下角,迷宫的进出口在左上角.当然,迷宫中的通路不是平坦 ...