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

统计--交叉表+日期+优先.sql

SQL code
   
   
-- 交叉表,根据优先级取数据,日期处理 create table tb(qid int ,rid nvarchar ( 4 ),tagname nvarchar ( 10 ),starttime smalldatetime ,endtime smalldatetime ,startweekday int ,endweekday int ,startdate smalldatetime ,enddate smalldatetime ,d int ) insert tb select 1 , ' A1 ' , ' 未订 ' , ' 08:00 ' , ' 09:00 ' , 1 , 5 , null , null , 1 union all select 1 , ' A1 ' , ' 未订 ' , ' 09:00 ' , ' 10:00 ' , 1 , 5 , null , null , 1 union all select 1 , ' A1 ' , ' 未订 ' , ' 10:00 ' , ' 11:00 ' , 1 , 5 , null , null , 1 union all select 1 , ' A1 ' , ' 装修 ' , ' 08:00 ' , ' 09:00 ' , null , null , ' 2005-1-18 ' , ' 2005-1-19 ' , 2 -- union all select 1,'A1','装修','09:00','10:00',null,null,'2005-1-18','2005-1-19',2 union all select 1 , ' A1 ' , ' 装修 ' , ' 10:00 ' , ' 11:00 ' , null , null , ' 2005-1-18 ' , ' 2005-1-19 ' , 2 union all select 1 , ' A2 ' , ' 未订 ' , ' 08:00 ' , ' 09:00 ' , 1 , 5 , null , null , 1 union all select 1 , ' A2 ' , ' 未订 ' , ' 09:00 ' , ' 10:00 ' , 1 , 5 , null , null , 1 union all select 1 , ' A2 ' , ' 未订 ' , ' 10:00 ' , ' 11:00 ' , 1 , 5 , null , null , 1 -- union all select 1,'A2','装修','08:00','09:00',null,null,'2005-1-18','2005-1-19',2 union all select 1 , ' A2 ' , ' 装修 ' , ' 09:00 ' , ' 10:00 ' , null , null , ' 2005-1-18 ' , ' 2005-1-19 ' , 2 -- union all select 1,'A2','装修','10:00','11:00',null,null,'2005-1-18','2005-1-19',2 go /* --楼主这个问题要考虑几个方面 1. 取星期时,set datefirst 的影响 2. 优先级问题 3. qid,rid 应该是未知的(动态变化的) -- */ -- 实现的存储过程如下 create proc p_qry @date smalldatetime -- 要查询的日期 as set nocount on declare @week int , @s nvarchar ( 4000 ) -- 格式化日期和得到星期 select @date = convert ( char ( 10 ), @date , 120 ) , @week = ( @@datefirst + datepart (weekday, @date ) - 1 ) % 7 , @s = '' select id = identity ( int ), * into #t from ( select top 100 percent qid,rid,tagname, starttime = convert ( char ( 5 ),starttime, 108 ), endtime = convert ( char ( 5 ),endtime, 108 ) from tb where ( @week between startweekday and endweekday) or ( @date between startdate and enddate) order by qid,rid,starttime,d desc )a select @s = @s + N ' ,[ ' + rtrim (rid) + N ' ]=max(case when qid= ' + rtrim (qid) + N ' and rid=N ''' + rtrim (rid) + N ''' then tagname else N '''' end) ' from #t group by qid,rid exec ( ' select starttime,endtime ' + @s + ' from #t a where not exists( select * from #t where qid=a.qid and rid=a.rid and starttime=a.starttime and endtime=a.endtime and id<a.id) group by starttime,endtime ' ) go -- 调用 exec p_qry ' 2005-1-17 ' exec p_qry ' 2005-1-18 ' go -- 删除测试 drop table tb drop proc p_qry /* --测试结果 starttime endtime A1 A2 --------- ------- ---------- ---------- 08:00 09:00 未订 未订 09:00 10:00 未订 未订 10:00 11:00 未订 未订 starttime endtime A1 A2 --------- ------- ---------- ---------- 08:00 09:00 装修 未订 09:00 10:00 未订 装修 10:00 11:00 装修 未订 -- */


各种字符串分拆处理函数.sql

SQL code
   
   
-- 各种字符串分函数 if exists ( select * from dbo.sysobjects where id = object_id (N ' [dbo].[f_splitSTR] ' ) and xtype in (N ' FN ' , N ' IF ' , N ' TF ' )) drop function [ dbo ] . [ f_splitSTR ] GO -- 3.2.1 循环截取法 CREATE FUNCTION f_splitSTR( @s varchar ( 8000 ), -- 待分拆的字符串 @split varchar ( 10 ) -- 数据分隔符 ) RETURNS @re TABLE (col varchar ( 100 )) AS BEGIN DECLARE @splitlen int SET @splitlen = LEN ( @split + ' a ' ) - 2 WHILE CHARINDEX ( @split , @s ) > 0 BEGIN INSERT @re VALUES ( LEFT ( @s , CHARINDEX ( @split , @s ) - 1 )) SET @s = STUFF ( @s , 1 , CHARINDEX ( @split , @s ) + @splitlen , '' ) END INSERT @re VALUES ( @s ) RETURN END GO /* ============================================== */ if exists ( select * from dbo.sysobjects where id = object_id (N ' [dbo].[f_splitSTR] ' ) and xtype in (N ' FN ' , N ' IF ' , N ' TF ' )) drop function [ dbo ] . [ f_splitSTR ] GO -- 3.2.3.1 使用临时性分拆辅助表法 CREATE FUNCTION f_splitSTR( @s varchar ( 8000 ), -- 待分拆的字符串 @split varchar ( 10 ) -- 数据分隔符 ) RETURNS @re TABLE (col varchar ( 100 )) AS BEGIN -- 创建分拆处理的辅助表(用户定义函数中只能操作表变量) DECLARE @t TABLE (ID int IDENTITY ,b bit ) INSERT @t (b) SELECT TOP 8000 0 FROM syscolumns a,syscolumns b INSERT @re SELECT SUBSTRING ( @s ,ID, CHARINDEX ( @split , @s + @split ,ID) - ID) FROM @t WHERE ID <= LEN ( @s + ' a ' ) AND CHARINDEX ( @split , @split + @s ,ID) = ID RETURN END GO /* ============================================== */ if exists ( select * from dbo.sysobjects where id = object_id (N ' [dbo].[f_splitSTR] ' ) and xtype in (N ' FN ' , N ' IF ' , N ' TF ' )) drop function [ dbo ] . [ f_splitSTR ] GO if exists ( select * from dbo.sysobjects where id = object_id (N ' [dbo].[tb_splitSTR] ' ) and objectproperty (id,N ' IsUserTable ' ) = 1 ) drop table [ dbo ] . [ tb_splitSTR ] GO -- 3.2.3.2 使用永久性分拆辅助表法 -- 字符串分拆辅助表 SELECT TOP 8000 ID = IDENTITY ( int , 1 , 1 ) INTO dbo.tb_splitSTR FROM syscolumns a,syscolumns b GO -- 字符串分拆处理函数 CREATE FUNCTION f_splitSTR( @s varchar ( 8000 ), -- 待分拆的字符串 @split varchar ( 10 ) -- 数据分隔符 ) RETURNS TABLE AS RETURN ( SELECT col = CAST ( SUBSTRING ( @s ,ID, CHARINDEX ( @split , @s + @split ,ID) - ID) as varchar ( 100 )) FROM tb_splitSTR WHERE ID <= LEN ( @s + ' a ' ) AND CHARINDEX ( @split , @split + @s ,ID) = ID) GO /* ============================================== */ if exists ( select * from dbo.sysobjects where id = object_id (N ' [dbo].[f_splitSTR] ' ) and xtype in (N ' FN ' , N ' IF ' , N ' TF ' )) drop function [ dbo ] . [ f_splitSTR ] GO -- 3.2.5 将数据项按数字与非数字再次拆份 CREATE FUNCTION f_splitSTR( @s varchar ( 8000 ), -- 待分拆的字符串 @split varchar ( 10 ) -- 数据分隔符 ) RETURNS @re TABLE (No varchar ( 100 ),Value varchar ( 20 )) AS BEGIN -- 创建分拆处理的辅助表(用户定义函数中只能操作表变量) DECLARE @t TABLE (ID int IDENTITY ,b bit ) INSERT @t (b) SELECT TOP 8000 0 FROM syscolumns a,syscolumns b INSERT @re SELECT No = REVERSE ( STUFF (col, 1 , PATINDEX ( ' %[^-^.^0-9]% ' ,col + ' a ' ) - 1 , '' )), Value = REVERSE ( LEFT (col, PATINDEX ( ' %[^-^.^0-9]% ' ,col + ' a ' ) - 1 )) FROM ( SELECT col = REVERSE ( SUBSTRING ( @s ,ID, CHARINDEX ( @split , @s + @split ,ID) - ID)) FROM @t WHERE ID <= LEN ( @s + ' a ' ) AND CHARINDEX ( @split , @split + @s ,ID) = ID)a RETURN END GO /* ============================================== */ if exists ( select * from dbo.sysobjects where id = object_id (N ' [dbo].[f_splitSTR] ' ) and xtype in (N ' FN ' , N ' IF ' , N ' TF ' )) drop function [ dbo ] . [ f_splitSTR ] GO -- 3.2.6 分拆短信数据 CREATE FUNCTION f_splitSTR( @s varchar ( 8000 )) RETURNS @re TABLE (split varchar ( 10 ),value varchar ( 100 )) AS BEGIN DECLARE @splits TABLE (split varchar ( 10 ),splitlen as LEN (split)) INSERT @splits (split) SELECT ' AC ' UNION ALL SELECT ' BC ' UNION ALL SELECT ' CC ' UNION ALL SELECT ' DC ' DECLARE @pos1 int , @pos2 int , @split varchar ( 10 ), @splitlen int SELECT TOP 1 @pos1 = 1 , @split = split, @splitlen = splitlen FROM @splits WHERE @s LIKE split + ' % ' WHILE @pos1 > 0 BEGIN SELECT TOP 1 @pos2 = CHARINDEX (split, @s , @splitlen + 1 ) FROM @splits WHERE CHARINDEX (split, @s , @splitlen + 1 ) > 0 ORDER BY CHARINDEX (split, @s , @splitlen + 1 ) IF @@ROWCOUNT = 0 BEGIN INSERT @re VALUES ( @split , STUFF ( @s , 1 , @splitlen , '' )) RETURN END ELSE BEGIN INSERT @re VALUES ( @split , SUBSTRING ( @s , @splitlen + 1 , @pos2 - @splitlen - 1 )) SELECT TOP 1 @pos1 = 1 , @split = split, @splitlen = splitlen, @s = STUFF ( @s , 1 , @pos2 - 1 , '' ) FROM @splits WHERE STUFF ( @s , 1 , @pos2 - 1 , '' ) LIKE split + ' % ' END END RETURN END GO
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值