SQLServer 一個簡單操作(續)



--======================== 

--設置內存選項 

--======================== 
 
--
設置 min server memory 配置項 
EXEC sp_configure N'min server memory (MB)',0  
--
設置 max server memory 配置項 
EXEC sp_configure N'max server memory (MB)',256  
--
使更新生效 
RECONFIGURE WITH OVERRIDE 
 
--============================================================ 
 
--======================== 

--使用文件及文件組.sql 

--======================== 
 
/*--
功能說明 下面的代碼是在SQL Server 2000上創建名爲 MyDB 的數據庫 
 
該數據庫包括1個主要數據文件、3個用戶定義的文件組和1個日誌文件 
 ALTER DATABASE
句將用戶定義文件組指定爲默認文件組。  
 
之後,通過指默認的文件組來創建表,並且將圖像數據和索引放到指定的文件組中。 
 
最後,將文件組中的指定數據文件刪除 --*/  
 --
切換到 master 數據庫 
 USE master 
 GO  
 --A. 
創建數據庫 MyDB 
 CREATE DATABASE MyDB 
    ON PRIMARY      --
主文件組和主要數據文件  
    (    NAME='MyDB_Primary',  
        FILENAME= 'c:/MyDB_Prm.mdf' 
    ), 
    FILEGROUP MyDB_FG1  --
用戶定義文件組1  
    ( 
         NAME= 'MyDB_FG1_Dat1',  
         FILENAME= 'c:/MyDB_FG1_1.ndf' 
    ), 
    --
次要數據文件1  
    (  
        NAME= 'MyDB_FG1_Dat2',  
        FILENAME= 'd:/MyDB_FG1_2.ndf' 
    ), 
    --
次要數據文件
    FILEGROUP MyDB_FG2--
用戶定義文件組2  
    (  
        NAME= 'MyDB_FG1_Dat',  
        FILENAME= 'e:/MyDB_FG2.ndf' 
    ), 
    --
次要數據文件LOG ON --日誌文件  
    (  
        NAME='MyDB_log',  
        FILENAME='d:/MyDB.ldf' 
    )  
 
--DUMP TRANSACTION MyDB WITH NO_LOG and truncate_only 
GO  
 
--B. 
修改默認數據文件組 
ALTER DATABASE MyDB  
    MODIFY FILEGROUP MyDB_FG1 DEFAULT 
GO 
---
切換到新建的數據庫 MyDB 
USE MyDB 
 
--C. 
在默認文件組MyDB_FG1創建表,並且指定圖像數據保存在用戶定義文件組MMyDB_FG2 
CREATE TABLE MyTable  
    (  
        cola int PRIMARY KEY ,  
        colb char(8) ,  
        colc image  
    )  
TEXT IMAGE_ON MyDB_FG2 
--
在用戶定義文件組MyDB_FG2上創建索引 
CREATE INDEX IX_MyTable 
    ON MyTable(cola) 
    ON MyDB_FG2 
GO  
     
--D. 
將要刪除數據文件MyDB_FG1_Dat1上的數據轉移到其他數據文件中, 
--   
並且清空數據文件MyDB_FG1_Dat1 
DBCC SHRINKFILE(MyDB_FG1_Dat1,EMPTYFILE) 
--
刪除數據文件MyDB_FG1_Dat1 
ALTER DATABASE MyDB REMOVE FILE MyDB_FG1_Dat1 
 
--========================================================================== 
 
--=============================== 

--調整tempdb數據庫的文件屬性.sql 

--=============================== 
 
--A. 
tempdb數據庫的主數據文件大小設置爲10MB 
ALTER DATABASE tempdb  
    MODIFY FILE( name=tempdev, size=100 MB) 
GO  
--B. 
tempdb數據庫的主數據文件移動到指定的磁盤分區上,並且爲其添加一個數據文件。 
--
移動主數據文件 
ALTER DATABASE tempdb  
    MODIFY FILE ( NAME='tempdev', FILENAME='d:/tempdb.mdf'
--
添加次要數據文件 
ALTER DATABASE tempdb 
    ADD FILE ( NAME='tempdata_1', FILENAME='d:/tempdb_data_1.ndf'
     
--============================================================================ 
 
--=============================== 

--日期概念理解中的一些測試.sql 

--=============================== 
 
--A. 
測試 datetime 精度問題 
DECLARE @t TABLE(date char(21)) 
INSERT @t SELECT '1900-1-1 00:00:00.000' 
INSERT @t SELECT '1900-1-1 00:00:00.001' 
INSERT @t SELECT '1900-1-1 00:00:00.009' 
INSERT @t SELECT '1900-1-1 00:00:00.002' 
INSERT @t SELECT '1900-1-1 00:00:00.003' 
INSERT @t SELECT '1900-1-1 00:00:00.004' 
INSERT @t SELECT '1900-1-1 00:00:00.005' 
INSERT @t SELECT '1900-1-1 00:00:00.006' 
INSERT @t SELECT '1900-1-1 00:00:00.007' 
INSERT @t SELECT '1900-1-1 00:00:00.008' 
SELECT date,
轉換後的日期=CAST(date as datetime
    FROM @t  
/*--
結果 date 轉換後的日期  
--------------------- --------------------------  
1900-1-1 00:00:00.000  
1900-01-01 00:00:00.000  
1900-1-1 00:00:00.001  
1900-01-01 00:00:00.000  
1900-1-1 00:00:00.009  
1900-01-01 00:00:00.010  
1900-1-1 00:00:00.002  
1900-01-01 00:00:00.003  
1900-1-1 00:00:00.003  
1900-01-01 00:00:00.003  
1900-1-1 00:00:00.004  
1900-01-01 00:00:00.003  
1900-1-1 00:00:00.005  
1900-01-01 00:00:00.007  
1900-1-1 00:00:00.006  
1900-01-01 00:00:00.007  
1900-1-1 00:00:00.007  
1900-01-01 00:00:00.007  
1900-1-1 00:00:00.008  
1900-01-01 00:00:00.007  
(所影響的行數爲 10 行) -- 
*/ 
GO  
--B. 
對於 datetime 類型的純日期和時間的十六進制表示 
DECLARE @dt datetime  
--
單純的日期 
    SET @dt='1900-1-2'SELECT CAST(@dt as binary(8)) 
    --
結果: 0x0000000100000000 
    --
單純的時間 
    SET @dt='00:00:01'SELECT CAST(@dt as binary(8)) 
--
結果: 0x000000000000012CGO  
--C. 
對於 smalldatetime 類型的純日期和時間的十六進制表示 
DECLARE @dt smalldatetime  
--
單純的日期 
    SET @dt='1900-1-2'SELECT CAST(@dt as binary(4)) 
    --
結果: 0x00010000 
    --
單純的時間 
    SET @dt='00:10'SELECT CAST(@dt as binary(4)) 
--
結果: 0x0000000A 
 
--====================================================================== 
 
--================================= 

--CONVERT在日期轉換中的使用示例.sql 

--================================= 
 
--
字符轉換爲日期時,Style的使用 
--1. Style=101
,表示日期字符串爲:mm/dd/yyyy格式 
SELECT CONVERT(datetime,'11/1/2003',101
--
結果:2003-11-01 00:00:00.000 
--2. Style=101
,表示日期字符串爲:dd/mm/yyyy格式 
SELECT CONVERT(datetime,'11/1/2003',103
--
結果:2003-01-11 00:00:00.000  
/*== 
日期轉換爲字符串 ==*/ 
DECLARE @dt datetime 
    SET @dt='2003-1-11'  
--1. Style=101
,表示將日期轉換爲:mm/dd/yyyy 格式 
SELECT CONVERT(varchar,@dt,101
--
結果:01/11/2003--2. Style=103,表示將日期轉換爲:dd/mm/yyyy 格式 
SELECT CONVERT(varchar,@dt,103
--
結果:11/01/2003  
/*== 
這是很多人經常犯的錯誤,對非日期型轉換使用日期的style樣式 ==*/ 
SELECT CONVERT(varchar,'2003-1-11',101
--
結果:2003-1-11 
 
 
--===================================================================== 
 
--============================= 

--SET DATEFORMAT對日期處理的影響.sql 

--============================= 
 
--1. 
/*-- 
說明 SET DATEFORMAT設置對使用CONVERT把字符型日期轉換爲日期的處理也具有影響  
但不影響明確指定了styleCONVERT處理。  
--*/  
--
示例 ,在下面的示例中,第一個CONVERT轉換未指定style,轉換的結果受SET DATAFORMAT 
--
影響,第二個CONVERT轉換指定了style,轉換結果受style的影響。 
--
設置輸入日期順序爲 // 
SET DATEFORMAT DMY 
--
不指定Style參數的CONVERT轉換將受到SET DATEFORMAT的影響 
SELECT CONVERT(datetime,'2-1-2005'
--
結果: 2005-01-02 00:00:00.000 
--
指定Style參數的CONVERT轉換不受SET DATEFORMAT的影響 
SELECT CONVERT(datetime,'2-1-2005',101
--
結果: 2005-02-01 00:00:00.000GO  
--2. 
/*-- 
說明 如果輸入的日期包含了世紀部分,則對日期進行解釋處理時  
年份的解釋不受SET DATEFORMAT設置的影響。  
--*/  
--
示例,在下面的代碼中,同樣的SET DATEFORMAT設置,輸入日期的世紀部分與不輸入日期的 
--
世紀部分,解釋的日期結果不同。 
DECLARE @dt datetime  
--
設置SET DATEFORMAT:月日年 
SET DATEFORMAT MDY 
--
輸入的日期中指定世紀部分 
SET @dt='01-2002-03'SELECT @dt 
--
結果: 2002-01-03 00:00:00.000 
--
輸入的日期中不指定世紀部分 
SET @dt='01-02-03'SELECT @dt 
--
結果: 2003-01-02 00:00:00.000GO  
--3. 
/*-- 
說明 如果輸入的日期不包含日期分隔符,那麼SQL Server在對日期進行解釋時  
將忽略SET DATEFORMAT的設置。  
--*/  
--
示例,在下面的代碼中,不包含日期分隔符的字符日期,在不同的SET DATEFORMAT設置下, 
--
其解釋的結果是一樣的。 
DECLARE @dt datetime  
--
設置SET DATEFORMAT:月日年 
SET DATEFORMAT MDY 
SET @dt='010203'SELECT @dt 
--
結果: 2001-02-03 00:00:00.000 
--
設置SET DATEFORMAT:日月年 
SET DATEFORMAT DMY 
SET @dt='010203'SELECT @dt 
--
結果: 2001-02-03 00:00:00.000 
--
輸入的日期中包含日期分隔符 
SET @dt='01-02-03'SELECT @dt 
--
結果: 2003-02-01 00:00:00.000 
 
--============================================================================== 
 
--=================================== 

--SET LANGUAGE對日期處理的影響示例.sql 

--=================================== 
 
--
以下示例演示了在不同的語言環境(SET LANGUAGE)下,DATENAMECONVERT函數的不同結果。 
USE master 
--
設置會話的語言環境爲: English 
SET LANGUAGE N'English' 
SELECT DATENAME(Month,GETDATE())AS [Month], 
    DATENAME(Weekday,GETDATE())AS [Weekday], 
    CONVERT(varchar,GETDATE(),109)AS [CONVERT] 
/*-- 
結果: Month Weekday CONVERT  
------------- -------------- -------------------------------  
March Tuesday Mar 15 2005 8:59PM 
 --*/  
 --
設置會話的語言環境爲簡體中文 
 SET LANGUAGE N'
簡體中文' 
 SELECT DATENAME(Month,GETDATE())AS [Month], 
     DATENAME(Weekday,GETDATE())AS [Weekday], 
     CONVERT(varchar,GETDATE(),109)AS [CONVERT] 
/*--
結果 Month Weekday CONVERT  
 ------------- --------------- ----------------------------------------- 
  05 
星期四 05 19 2005 2:49:20:607PM  
--*/ 
   
  --======================================================================= 
   
  --================================== 

--日期格式化處理.sql 

  --================================== 
 
DECLARE @dt datetime 
SET @dt=GETDATE() 
--1
.短日期格式:yyyy-m-d 
SELECT REPLACE(CONVERT(varchar(10),@dt,120),N'-0','-'
--2
.長日期格式:yyyymmdd 
--A. 
方法
SELECT STUFF(STUFF(CONVERT(char(8),@dt,112),5,0,N'
'),8,0,N'')+N'' 
--B. 
方法
SELECT DATENAME(Year,@dt)+N'
' 
    +DATENAME(Month,@dt)+N'
' 
    +DATENAME(Day,@dt)+N'
'  
--3
.長日期格式:yyyymd 
SELECT DATENAME(Year,@dt)+N'
' 
    +CAST(DATEPART(Month,@dt)AS varchar)+N'
' 
    +DATENAME(Day,@dt)+N'
'  
--4.
完整日期+時間格式:yyyy-mm-dd hh:mi:ss:mmm 
SELECT CONVERT(char(11),@dt,120)+CONVERT(char(12),@dt,114
 
--================================================================ 
 
--======================== 

--日期推算處理.sql 

--======================== 
 
DECLARE @dt datetime 
SET @dt=GETDATE() 
DECLARE @number int 
SET @number=3  
--1
.指定日期該年的第一天或最後一天 
--A. 
年的第一天 
SELECT CONVERT(char(5),@dt,120)+'1-1'  
--B. 
年的最後一天 
SELECT CONVERT(char(5),@dt,120)+'12-31'  
--2
.指定日期所在季度的第一天或最後一天 
--A. 
季度的第一天 
SELECT CONVERT(datetime,CONVERT(char(8), 
    DATEADD(Month,DATEPART(Quarter,@dt)*3 
    -Month(@dt)-2,@dt),120)+'1'
--B. 
季度的最後一天(CASE判斷法) 
SELECT CONVERT(datetime,CONVERT(char(8), 
    DATEADD(Month,DATEPART(Quarter,@dt)*3-Month(@dt),@dt),120
    +CASE WHEN DATEPART(Quarter,@dt)in(1,4)THEN '31'ELSE '30' END
--C. 
季度的最後一天(直接推算法) 
SELECT DATEADD(Day,-1,CONVERT(char(8), 
    DATEADD(Month,1+DATEPART(Quarter,@dt)*3-Month(@dt),@dt),120)+'1'
--3
.指定日期所在月份的第一天或最後一天 
--A. 
月的第一天 
SELECT CONVERT(datetime,CONVERT(char(8),@dt,120)+'1'
--B. 
月的最後一天 
SELECT DATEADD(Day,-1,CONVERT(char(8),DATEADD(Month,1,@dt),120)+'1'
--C. 
月的最後一天(容易使用的錯誤方法) 
SELECT DATEADD(Month,1,DATEADD(Day,-DAY(@dt),@dt)) 
--4
.指定日期所在周的任意一天 
SELECT DATEADD(Day,@number-DATEPART(Weekday,@dt),@dt) 
--5
.指定日期所在周的任意星期幾 
--A. 
星期天做爲一週的第1 
SELECT DATEADD(Day,@number-(DATEPART(Weekday,@dt)+@@DATEFIRST-1)%7,@dt) 
--B. 
星期一做爲一週的第1 
SELECT DATEADD(Day,@number-(DATEPART(Weekday,@dt)+@@DATEFIRST-2)%7-1,@dt) 
 
--============================================================================ 
 
--================================ 

--查詢指定日期段內過生日的人員.sql 

--================================ 
 
--
測試數據 
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 @t 
    WHERE 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.000  
 7 bb 1989-12-11 00:00:00.000  
 --*/  
 --
查詢 2003-12-05  2006-02-28 生日的記錄 
 SET @dt2='2006-02-28' 
 SELECT * FROM @t 
    WHERE 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.000  
2 bb 1996-02-29 00:00:00.000  
7 bb 1989-12-11 00:00:00.000  
--*/ 
 
--========================================================================= 
 
--========================== 

--生成日期列表的函數.sql 

--========================== 
 
DECLARE @dt datetime 
SET @dt=GETDATE() 
DECLARE @number int 
SET @number=3  
--1
.指定日期該年的第一天或最後一天 
--A. 
年的第一天 
SELECT CONVERT(char(5),@dt,120)+'1-1'  
--B. 
年的最後一天 
SELECT CONVERT(char(5),@dt,120)+'12-31'  
--2
.指定日期所在季度的第一天或最後一天 
--A. 
季度的第一天 
SELECT CONVERT(datetime
    CONVERT(char(8),DATEADD(Month,DATEPART(Quarter,@dt)*3-Month(@dt)-2,@dt),120)+'1'
--B. 
季度的最後一天(CASE判斷法) 
SELECT CONVERT(datetime
    CONVERT(char(8),DATEADD(Month,DATEPART(Quarter,@dt)*3-Month(@dt),@dt),120
    +CASE WHEN DATEPART(Quarter,@dt)in(1,4)THEN '31'ELSE '30' END
--C. 
季度的最後一天(直接推算法) 
SELECT DATEADD(Day,-1
    CONVERT(char(8),DATEADD(Month,1+DATEPART(Quarter,@dt)*3-Month(@dt),@dt),120)+'1'
--3
.指定日期所在月份的第一天或最後一天 
--A. 
月的第一天 
SELECT CONVERT(datetime,CONVERT(char(8),@dt,120)+'1'
--B. 
月的最後一天 
SELECT DATEADD(Day,-1,CONVERT(char(8),DATEADD(Month,1,@dt),120)+'1'
--C. 
月的最後一天(容易使用的錯誤方法) 
SELECT DATEADD(Month,1,DATEADD(Day,-DAY(@dt),@dt)) 
--4
.指定日期所在周的任意一天 
SELECT DATEADD(Day,@number-DATEPART(Weekday,@dt),@dt) 
--5
.指定日期所在周的任意星期幾 
--A. 
星期天做爲一週的第1 
SELECT DATEADD(Day,@number-(DATEPART(Weekday,@dt)+@@DATEFIRST-1)%7,@dt) 
--B. 
星期一做爲一週的第1 
SELECT DATEADD(Day,@number-(DATEPART(Weekday,@dt)+@@DATEFIRST-2)%7-1,@dt) 
 
--========================================================================= 
 
--=================== 

--複雜年月處理.sql 

--=================== 
 
--
定義基本數字表 
declare @T1 table(
代碼 int,名稱 varchar(10),參加時間 datetime,終止時間 datetime
insert into @T1 select 12,'
單位1','2003/04/01','2004/05/01' union all  
select 22,'
單位2','2001/02/01','2003/02/01' union all  
select 42,'
單位3','2000/04/01','2003/05/01' union all  
select 25,'
單位5','2003/04/01','2003/05/01'  
--
定義年表 
declare @NB table(
代碼 int,名稱 varchar(10),年份 int
insert into @NB  
    select 12,'
單位1',2003 union all  
    select 12,'
單位1',2004 union all  
    select 22,'
單位2',2001 union all  
    select 22,'
單位2',2002 union all  
    select 22,'
單位2',2003  
--
定義月表 
declare @YB table(
代碼 int,名稱 varchar(10),年份 int,月份 varchar(2)) 
insert into @YB  
    select 12,'
單位1',2003,'04' union all  
    select 22,'
單位2',2001,'01' union all  
    select 22,'
單位2',2001,'12'  
--
爲年表+月表數據處理準備臨時表 
select top 8246 y=identity(int,1753,1)into #tby from  
    (select id from syscolumns) a,  
    (select id from syscolumns) b,  
    (select id from syscolumns) c 
--
爲月表數據處理準備臨時表 
select top 12 m=identity(int,1,1)into #tbm from syscolumns 
/*--
數據處理--*/ 
--
年表數據處理 
select a.*from 
    (select a.
代碼,a.名稱,年份=b.y from @T1 a,#tby b  
        where b.y between year(
參加時間)and year(終止時間) )  
        a left join @NB b  
        on a.
代碼=b.代碼 and a.年份=b.年份  
        where b.
代碼 is null  
--
月表數據處理 
select a.* from 
    (select a.
代碼,a.名稱,年份=b.y, 
    
月份=right('00'+cast(c.m as varchar),2)from @T1 a,#tby b,#tbm c  
        where b.y*100+c.m between  
            convert(varchar(6),
參加時間,112)and convert(varchar(6),終止時間,112) ) a  
        left join @YB b on a.
代碼=b.代碼  
            and a.
年份=b.年份  
            and a.
月份=b.月份 where b.代碼 is null  
        order by a.
代碼,a.名稱,a.年份,a.月份 
--
刪除數據處理臨時表 
drop table #tby,#tbm 
 
--========================================================================= 
 
--============================ 

--交叉表.sql 

--============================ 
 
--
示例--示例數據 
create table tb(ID int,Time datetime
insert tb  
    select 1,'2005/01/24 16:20'union all  
    select 2,'2005/01/23 22:45'union all  
    select 3,'2005/01/23 0:30'union all  
    select 4,'2005/01/21 4:28'union all  
    select 5,'2005/01/20 13:22'union all  
    select 6,'2005/01/19 20:30'union all  
    select 7,'2005/01/19 18:23'union all  
    select 8,'2005/01/18 9:14'union all  
    select 9,'2005/01/18 18:04' 
go  
--
查詢處理: 
select case when grouping(b.Time)=1  
    then 'Total'  
    else b.Time end
    [Mon]=sum(case a.week when 1 then 1 else 0 end), 
    [Tue]=sum(case a.week when 2 then 1 else 0 end), 
    [Wed]=sum(case a.week when 3 then 1 else 0 end), 
    [Thu]=sum(case a.week when 4 then 1 else 0 end), 
    [Fri]=sum(case a.week when 5 then 1 else 0 end), 
    [Sat]=sum(case a.week when 6 then 1 else 0 end), 
    [Sun]=sum(case a.week when 0 then 1 else 0 end), 
    [Total]=count(a.week)from 
        (select Time=convert(char(5),dateadd(hour,-1,Time),108), 
        --
時間交界點是1am,所以減1小時,避免進行跨天處理  
        week=(@@datefirst+datepart(weekday,Time)-1)%7  
        --
考慮@@datefirstdatepart的影響  
            from tb ) a  
            right join 
            (select id=1,a='16:00',b='19:59',Time='[5pm - 9pm)' union all  
            select id=2,a='20:00',b='23:59',Time='[9pm - 1am)' union all  
            select id=3,a='00:00',b='02:59',Time='[1am - 4am)' union all  
            select id=4,a='03:00',b='07:29',Time='[4am - 8:30am)' union all  
            select id=5,a='07:30',b='11:59',Time='[8:30am - 1pm)' union all  
            select id=6,a='12:00',b='15:59',Time='[1pm - 5pm)')  
            b on a.Time>=b.a and a.Time<b.b  
            group by b.id,b.Time  
            with rollup having grouping(b.Time)=0 or grouping(b.id)=1 
go  
--</b.b  
刪除測試 
drop table tb 
/*-- 
測試結果 Mon Tue Wed Thu Fri Sat Sun Total  
-------------- ----- ----- ----- ----- ----- ------ ---- -------  
[5pm - 9pm) 0 1 2 0 0 0 0 3  
[9pm - 1am) 0 0 0 0 0 0 2 2  
[1am - 4am) 0 0 0 0 0 0 0 0  
[4am - 8:30am) 0 0 0 0 1 0 0 1  
[8:30am - 1pm) 0 1 0 0 0 0 0 1  
[1pm - 5pm) 1 0 0 1 0 0 0 2  
Total 1 2 2 1 1 0 2 9 
 
所影響的行數爲 7 行)  
--*/ 
 
--======================================================================= 
 
--====================== 

--統計:交叉表+日期+優先.sql 

--===================== 
 
--
交叉表,根據優先級取數據,日期處理 
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,108from 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 
--</a.id)  
調用 
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 

--======================== 
 
--
各種字符串分函數 

--3.3.1 使用遊標法進行字符串合併處理的示例。 

--處理的數據 
CREATE TABLE tb(col1 varchar(10),col2 int
INSERT tb SELECT 'a',1UNION ALL  
    SELECT 'a',2UNION ALL  
    SELECT 'b',1UNION ALL  
    SELECT 'b',2UNION ALL  
    SELECT 'b',3  
--
合併處理--定義結果集表變量 
DECLARE @t TABLE(col1 varchar(10),col2 varchar(100)) 
--
定義遊標並進行合併處理 
DECLARE tb CURSOR LOCAL FOR  
    SELECT col1,col2 FROM tb  
    ORDER BY col1,col2 
    DECLARE @col1_old varchar(10),@col1 varchar(10), 
            @col2 int,@s varchar(100
OPEN tb  
FETCH tb INTO @col1,@col2 
SELECT @col1_old=@col1,@s='' 
    WHILE @@FETCH_STATUS=0 
    BEGIN  
        IF @col1=@col1_old  
            SELECT @s=@s+','+CAST(@col2 as varchar
        ELSE  
            BEGIN  
                INSERT @t VALUES(@col1_old,STUFF(@s,1,1,'')) 
                SELECT @s=','+CAST(@col2 as varchar),@col1_old=@col1  
            END  
        FETCH tb INTO @col1,@col2  
    END  
INSERT @t VALUES(@col1_old,STUFF(@s,1,1,'')) 
CLOSE tb  
DEALLOCATE tb 
--
顯示結果並刪除測試數據 
SELECT * FROM @t 
DROP TABLE tb 
/*-- 
結果 col1 col2  
---------- -----------  
a 1,2 b 1,2,3  
--*/ 
GO  
/*==============================================*/  

--3.3.2 使用用戶定義函數,配合SELECT處理完成字符串合併處理的示例--處理的數據 

CREATE TABLE tb(col1 varchar(10),col2 int
INSERT tb  
    SELECT 'a',1UNION ALL  
    SELECT 'a',2UNION ALL  
    SELECT 'b',1UNION ALL  
    SELECT 'b',2UNION ALL  
    SELECT 'b',3 
    GO  
--
合併處理函數 
CREATE FUNCTION dbo.f_str(@col1 varchar(10))RETURNS varchar(100
    AS  
    BEGIN  
        DECLARE @re varchar(100
        SET @re=''  
        SELECT @re=@re+','+CAST(col2 as varchar
            FROM tb WHERE col1=@col1  
            RETURN(STUFF(@re,1,1,'')) 
    END 
GO  
--
調用函數 
SELECT col1,col2=dbo.f_str(col1) 
    FROM tb GROUP BY col1 
--
刪除測試 
DROP TABLE tb  
DROP FUNCTION f_str 
/*--
結果 col1 col2  
---------- -----------  
a 1,2 b 1,2,3 -- 
*/ 
GO 
/*==============================================*/ 
--==================================================================== 

--3.3.3 使用臨時表實現字符串合併處理的示例 

--處理的數據 
CREATE TABLE tb(col1 varchar(10),col2 int
INSERT tb SELECT 'a',1 
UNION ALL SELECT 'a',2 
UNION ALL SELECT 'b',1 
UNION ALL SELECT 'b',2 
UNION ALL SELECT 'b',3 
 
--
合併處理 
SELECT col1,col2=CAST(col2 as varchar(100)) 
INTO #t FROM tb 
ORDER BY col1,col2 
DECLARE @col1 varchar(10),@col2 varchar(100
UPDATE #t 
    SET @col2=CASE  
        WHEN @col1=col1  
            THEN @col2+','+col2  
            ELSE col2 
        END
        @col1=col1, 
        col2=@col2 
    SELECT * FROM #t 
/*--
更新處理後的臨時表 
col1       col2 
---------- ------------- 
a          1 
a          1,2 
b          1 
b          1,2 
b          1,2,3 
--*/ 
--
得到最終結果 
SELECT col1,col2=MAX(col2)FROM #t GROUP BY col1 
/*--
結果 
col1       col2 
---------- ----------- 
a          1,2 
b          1,2,3 
--*/ 
--
刪除測試 
DROP TABLE tb,#t 
GO 
 
 
/*==============================================*/ 
--=============================================================== 
 

--3.3.4.1 每組 <=2 條記錄的合併 

--處理的數據 
CREATE TABLE tb(col1 varchar(10),col2 int
INSERT tb SELECT 'a',1 
UNION ALL SELECT 'a',2 
UNION ALL SELECT 'b',1 
UNION ALL SELECT 'b',2 
UNION ALL SELECT 'c',3 
 
--
合併處理 
SELECT col1, 
    col2=CAST(MIN(col2)as varchar
       +CASE  
           WHEN COUNT(*)=1 THEN '' 
           ELSE ','+CAST(MAX(col2)as varchar
       END 
FROM tb 
GROUP BY col1 
DROP TABLE tb 
/*--
結果 
col1       col2      
 ---------- ---------- 
a          1,2 
b          1,2 
c          3 
--*/ 
 

--3.3.4.2 每組 <=3 條記錄的合併 

--處理的數據 
CREATE TABLE tb(col1 varchar(10),col2 int
INSERT tb SELECT 'a',1 
UNION ALL SELECT 'a',2 
UNION ALL SELECT 'b',1 
UNION ALL SELECT 'b',2 
UNION ALL SELECT 'b',3 
UNION ALL SELECT 'c',3 
--
QQ291911320 
--
合併處理 
SELECT col1, 
    col2=CAST(MIN(col2)as varchar
       +CASE  
           WHEN COUNT(*)=3 THEN ',' 
               +CAST((SELECT col2 FROM tb WHERE col1=a.col1 AND col2 NOT IN(MAX(a.col2),MIN(a.col2)))as varchar
           ELSE '' 
       END 
       +CASE  
           WHEN COUNT(*)>=2 THEN ','+CAST(MAX(col2)as varchar
           ELSE '' 
       END 
FROM tb a 
GROUP BY col1 
DROP TABLE tb 
/*--
結果 
col1       col2 
---------- ------------ 
a          1,2 
b          1,2,3 
c          3 
--*/ 
GO

發佈了23 篇原創文章 · 獲贊 4 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章