T-SQL: 17 个与日期时间相关的自定义函数(UDF),周日作为周的最后一天,均不受 @@DateFirst、语言版本影响!
原文: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、语言版本影响!的更多相关文章
- 大数据学习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 ...
- Sql Server中常用的6个自定义函数分享
转自:http://www.jb51.net/article/56691.htm IF OBJECT_ID('DBO.DISTINCT_STR') IS NOT NULL DROP FUNCTION ...
- 自定义函数导致的sql性能问题
同事说,某某报表跑的很慢,让我调查一下 优化前:该报表整体需要跑4小时以上. sql代码如下 SELECT /*省略多数查询字段*/ REP_FUN_REFCODEVALUE /*自定义函数*/ (P ...
- [转载]SQL语句中的日期计算
1. 本月的第一天SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0) 2. 本月的最后一天SELECT dateadd(ms,-3,DATEADD( ...
- jdbc 日期时间相关的类型
jdbc 日期时间相关的类型 1.sql.Date sql包中的日期类Date是util包中Date类的子类,实际上也是util.Date类的子集.它只处理年月日,而忽略小时和分秒,用以代表SQL的D ...
- Java_日期时间相关类
目录 Date类(java.util.date) Calendar类(java.util.Calendar) SimpleDateFormat类(java.text.SimpleDateFormat) ...
- PL/SQL学习笔记之日期时间
一:PL/SQL时间相关类型 PL/SQL提供两个和日期时间相关的数据类型: 日期时间(Datetime)数据类型 时间间隔类型 二:日期时间类型 datetime数据类型有: DATE TIMEST ...
- SQL Fundamentals || Single-Row Functions || 日期函数date functions
SQL Fundamentals || Oracle SQL语言 SQL Fundamentals: Using Single-Row Functions to Customize Output使 ...
- sql server中的日期详解使用(convert)
转自:http://blog.csdn.net/hehe520347/article/details/48496853 有个字段值例如2012-07-02 00:00:00.000 转化成 2012- ...
随机推荐
- 有关windows在调试ODOO8.0有些问题
继Ubuntu建筑物8.0调试环境后,,尝试windows设置开发环境. 最后的调试和开发,或将返回Linux环境,由于前一段时间手贱,改变分区表,该grub搞哈.哎!后来重建mbr,手动检索分区表( ...
- atitit.无损传输二进制数据串传输网络
atitit.无损传输二进制数据串传输网络 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 1 2. base64 2 3. iso-8859-1 (推荐) 2 4. utf-8 ...
- CentOS7 安装Hbase集群
继续接上一章,已安装好Hadoop集群环境 http://www.cnblogs.com/dopeter/p/4612232.html 在此基础上继续安装Hbase集群 Hbase版本为1.0.1.1 ...
- C/C++基础笔试题1.1.2(十问解决方案运营商)
他写在博客上不负责任,有人踩在上面,原因一点点失去了它. 其实纯常见问题.特别糟糕,由于鲍文看起来很大的优势就是想更直接看到的东西. 好了.返回整个标题. 1.你脑海中的运算符有哪些.按优先级排个序? ...
- DEV GridView嵌套
近来的DEV搞更多.试图寻找专业点的程序做,对这样一个小小的研究. 本篇是多么真实,现在的记录,可以通过点击这条线的子表的内容相关联的行中打开的列表.的影响,如下面的: 以下是实现过程: 1.设计器里 ...
- 如何用Excel直接查询Oracle中的数据(转)
将Oracle中查询的数据保存为Excel文件,通常使用的是PL/SQL Developer. 其实,Excel可直接写SQL语句查询Oracle中数据,在这里,用到ODBC驱动.详细步骤如下: 一. ...
- 一个非常不错的gridview 风格
<style type="text/css"> <!-- .datable {background-color: #9FD6FF; color:#333333; ...
- SSIS从理论到实战,再到应用(5)----流程控制之Foreach循环
原文:SSIS从理论到实战,再到应用(5)----流程控制之Foreach循环 上期回顾: SSIS从理论到实战,再到应用(4)----流程控制之For循环 上一期讲了For循环,Foreach循环相 ...
- 变焦控制ZoomControls
在安卓的webview中有这个点击放大缩小button,当时就在想如何实现那种效果,弄一个两个图标的ImageButton.但感觉又有些麻烦,昨天看疯狂安卓书.无意中发现另一个 ZoomButtons ...
- lua学习笔记10:lua简单的命令行
前面反复使用的命令行,好学喜欢命令行: 一 格公式 lua [options][script][args] 两 详细命令 -e 直接命令传递一个lua -l 加载文件 -i 进入交互模式 比例如.端子 ...