SQL大全(很强大)第四部分

来源:互联网 发布:时间规划软件 编辑:程序博客网 时间:2024/06/04 23:25

特殊日期加减函数.sql

SQL code
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_DateADD]') and xtype in (N'FN', N'IF', N'TF')) drop function [dbo].[f_DateADD]GO/*--特殊日期加减函数 对于日期指定部分的加减,使用DATEADD函数就可以轻松实现。 在实际的处理中,还有一种比较另类的日期加减处理 就是在指定的日期中,加上(或者减去)多个日期部分 比如将2005年3月11日,加上1年3个月11天2小时。 对于这种日期的加减处理,DATEADD函数的力量就显得有点不够。 本函数实现这样格式的日期字符串加减处理: y-m-d h:m:s.m | -y-m-d h:m:s.m 说明: 要加减的日期字符输入方式与日期字符串相同。日期与时间部分用空格分隔 最前面一个字符如果是减号(-)的话,表示做减法处理,否则做加法处理。 如果日期字符只包含数字,则视为日期字符中,仅包含天的信息。--*//*--调用示例 SELECT dbo.f_DateADD(GETDATE(),'11:10')--*/CREATE FUNCTION dbo.f_DateADD(@Date datetime,@DateStr varchar(23))RETURNS datetimeASBEGIN DECLARE @bz int,@s varchar(12),@i int IF @DateStr IS NULL OR @Date IS NULL OR(CHARINDEX('.',@DateStr)>0 AND @DateStr NOT LIKE '%[:]%[:]%.%') RETURN(NULL) IF @DateStr='' RETURN(@Date) SELECT @bz=CASE WHEN LEFT(@DateStr,1)='-' THEN -1 ELSE 1 END, @DateStr=CASE WHEN LEFT(@Date,1)='-' THEN STUFF(RTRIM(LTRIM(@DateStr)),1,1,'') ELSE RTRIM(LTRIM(@DateStr)) END IF CHARINDEX(' ',@DateStr)>1 OR CHARINDEX('-',@DateStr)>1 OR(CHARINDEX('.',@DateStr)=0 AND CHARINDEX(':',@DateStr)=0) BEGIN SELECT @i=CHARINDEX(' ',@DateStr+' ') ,@s=REVERSE(LEFT(@DateStr,@i-1))+'-' ,@DateStr=STUFF(@DateStr,1,@i,'') ,@i=0 WHILE @s>'' and @i<3 SELECT @Date=CASE @i WHEN 0 THEN DATEADD(Day,@bz*REVERSE(LEFT(@s,CHARINDEX('-',@s)-1)),@Date) WHEN 1 THEN DATEADD(Month,@bz*REVERSE(LEFT(@s,CHARINDEX('-',@s)-1)),@Date) WHEN 2 THEN DATEADD(Year,@bz*REVERSE(LEFT(@s,CHARINDEX('-',@s)-1)),@Date) END, @s=STUFF(@s,1,CHARINDEX('-',@s),''), @i=@i+1 END IF @DateStr>'' BEGIN IF CHARINDEX('.',@DateStr)>0 SELECT @Date=DATEADD(Millisecond ,@bz*STUFF(@DateStr,1,CHARINDEX('.',@DateStr),''), @Date), @DateStr=LEFT(@DateStr,CHARINDEX('.',@DateStr)-1)+':', @i=0 ELSE SELECT @DateStr=@DateStr+':',@i=0 WHILE @DateStr>'' and @i<3 SELECT @Date=CASE @i WHEN 0 THEN DATEADD(Hour,@bz*LEFT(@DateStr,CHARINDEX(':',@DateStr)-1),@Date) WHEN 1 THEN DATEADD(Minute,@bz*LEFT(@DateStr,CHARINDEX(':',@DateStr)-1),@Date) WHEN 2 THEN DATEADD(Second,@bz*LEFT(@DateStr,CHARINDEX(':',@DateStr)-1),@Date) END, @DateStr=STUFF(@DateStr,1,CHARINDEX(':',@DateStr),''), @i=@i+1 END RETURN(@Date)ENDGO


查询指定日期段内过生日的人员.sql

SQL code
--测试数据DECLARE @t TABLE(ID int,Name varchar(10),Birthday datetime)INSERT @t SELECT 1,'aa','1999-01-01'UNION ALL SELECT 2,'bb','1996-02-29'UNION ALL SELECT 3,'bb','1934-03-01'UNION ALL SELECT 4,'bb','1966-04-01'UNION ALL SELECT 5,'bb','1997-05-01'UNION ALL SELECT 6,'bb','1922-11-21'UNION ALL SELECT 7,'bb','1989-12-11'DECLARE @dt1 datetime,@dt2 datetime--查询 2003-12-05 至 2004-02-28 生日的记录SELECT @dt1='2003-12-05',@dt2='2004-02-28'SELECT * FROM @tWHERE DATEADD(Year,DATEDIFF(Year,Birthday,@dt1),Birthday) BETWEEN @dt1 AND @dt2 OR DATEADD(Year,DATEDIFF(Year,Birthday,@dt2),Birthday) BETWEEN @dt1 AND @dt2/*--结果ID Name Birthday---------------- ---------------- --------------------------1 aa 1999-01-01 00:00:00.0007 bb 1989-12-11 00:00:00.000--*/--查询 2003-12-05 至 2006-02-28 生日的记录SET @dt2='2006-02-28'SELECT * FROM @tWHERE DATEADD(Year,DATEDIFF(Year,Birthday,@dt1),Birthday) BETWEEN @dt1 AND @dt2 OR DATEADD(Year,DATEDIFF(Year,Birthday,@dt2),Birthday) BETWEEN @dt1 AND @dt2/*--查询结果ID Name Birthday---------------- ----------------- --------------------------1 aa 1999-01-01 00:00:00.0002 bb 1996-02-29 00:00:00.0007 bb 1989-12-11 00:00:00.000--*/


生成日期列表的函数.sql

SQL code
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_getdate]') and xtype in (N'FN', N'IF', N'TF'))drop function [dbo].[f_getdate]GO/*--生成日期列表 生成指定年份的工作日/休息日列表--邹建 2003.12(引用请保留此信息)--*//*--调用示例 --查询 2003 年的工作日列表 SELECT * FROM dbo.f_getdate(2003,0) --查询 2003 年的休息日列表 SELECT * FROM dbo.f_getdate(2003,1) --查询 2003 年全部日期列表 SELECT * FROM dbo.f_getdate(2003,NULL)--*/CREATE FUNCTION dbo.f_getdate(@year int, --要查询的年份@bz bit --@bz=0 查询工作日,@bz=1 查询休息日,@bz IS NULL 查询全部日期)RETURNS @re TABLE(id int identity(1,1),Date datetime,Weekday nvarchar(3))ASBEGIN DECLARE @tb TABLE(ID int IDENTITY(0,1),Date datetime) INSERT INTO @tb(Date) SELECT TOP 366 DATEADD(Year,@YEAR-1900,'1900-1-1') FROM sysobjects a ,sysobjects b UPDATE @tb SET Date=DATEADD(DAY,id,Date) DELETE FROM @tb WHERE Date>DATEADD(Year,@YEAR-1900,'1900-12-31') IF @bz=0 INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM @tb WHERE (DATEPART(Weekday,Date)+@@DATEFIRST-1)%7 BETWEEN 1 AND 5 ELSE IF @bz=1 INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM @tb WHERE (DATEPART(Weekday,Date)+@@DATEFIRST-1)%7 IN (0,6) ELSE INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM @tb RETURNENDGO/*====================================================================*/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_getdate]') and xtype in (N'FN', N'IF', N'TF'))drop function [dbo].[f_getdate]GO/*--生成列表 生成指定日期段的日期列表--邹建 2005.03(引用请保留此信息)--*//*--调用示例 --查询工作日 SELECT * FROM dbo.f_getdate('2005-1-3','2005-4-5',0) --查询休息日 SELECT * FROM dbo.f_getdate('2005-1-3','2005-4-5',1) --查询全部日期 SELECT * FROM dbo.f_getdate('2005-1-3','2005-4-5',NULL)--*/CREATE FUNCTION dbo.f_getdate(@begin_date Datetime, --要查询的开始日期@end_date Datetime, --要查询的结束日期@bz bit --@bz=0 查询工作日,@bz=1 查询休息日,@bz IS NULL 查询全部日期)RETURNS @re TABLE(id int identity(1,1),Date datetime,Weekday nvarchar(3))ASBEGIN DECLARE @tb TABLE(ID int IDENTITY(0,1),a bit) INSERT INTO @tb(a) SELECT TOP 366 0 FROM sysobjects a ,sysobjects b IF @bz=0 WHILE @begin_date<=@end_date BEGIN INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM( SELECT Date=DATEADD(Day,ID,@begin_date) FROM @tb )a WHERE Date<=@end_date AND (DATEPART(Weekday,Date)+@@DATEFIRST-1)%7 BETWEEN 1 AND 5 SET @begin_date=DATEADD(Day,366,@begin_date) END ELSE IF @bz=1 WHILE @begin_date<=@end_date BEGIN INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM( SELECT Date=DATEADD(Day,ID,@begin_date) FROM @tb )a WHERE Date<=@end_date AND (DATEPART(Weekday,Date)+@@DATEFIRST-1)%7 in(0,6) SET @begin_date=DATEADD(Day,366,@begin_date) END ELSE WHILE @begin_date<=@end_date BEGIN INSERT INTO @re(Date,Weekday) SELECT Date,DATENAME(Weekday,Date) FROM( SELECT Date=DATEADD(Day,ID,@begin_date) FROM @tb )a WHERE Date<=@end_date SET @begin_date=DATEADD(Day,366,@begin_date) END RETURN
END
GO