1. 程式人生 > >sql server 建立動態交叉表

sql server 建立動態交叉表

我所瞭解的建立動態交叉表有兩種方法,如下圖,有這樣一張銷售表 ,我想統計個人的銷售業績,如圖二表示出來,

建立銷售表

CREATE TABLE [dbo].[銷售](
	[ID] [int] NOT NULL,
	[員工姓名] [nvarchar](25) NULL,
	[所在部門] [nvarchar](15) NULL,
	[銷售業績] [int] NULL
) ON [PRIMARY]

 圖一,圖二

方法一:使用遊標建立動態交叉表

CREATE procedure Corss   
@strTabName as varchar(50) = '銷售',  
@strCol as varchar(50) = '所在部門',  
@strGroup as varchar(50) = '員工姓名',--分組欄位  
@strNumber as varchar(50) = '銷售業績', --被統計的欄位  
@strSum as varchar(10) = 'Sum' --運算方式  
AS  
DECLARE @strSql as varchar(1000), @strTmpCol as varchar(100)  
EXECUTE ('DECLARE corss_cursor CURSOR FOR SELECT DISTINCT ' + @strCol + ' from ' + @strTabName + ' for read only ') --生成遊標  
begin  
SET nocount ON   
SET @strsql ='select ' + @strGroup + ', ' + @strSum + '(' + @strNumber + ') AS [' + @strNumber + ']' --查詢的前半段  
OPEN corss_cursor  
while (0=0)  
BEGIN  
FETCH NEXT FROM corss_cursor --遍歷遊標,將列頭資訊放入變數@strTmpCol  
INTO @strTmpCol  
if (@@fetch_status<>0) break  
SET @strsql = @strsql + ', ' + @strSum + '(CASE ' + @strCol + ' WHEN ''' + @strTmpCol + ''' THEN ' + @strNumber + ' ELSE Null END) AS ['  + @strTmpCol +  ']' --構造查詢  
END  
SET @strsql = @strsql + ' from ' + @strTabname + ' group by ' + @strGroup --查詢結尾  
EXECUTE(@strsql) --執行  
IF @@error <>0 RETURN @@error --如果出錯,返回錯誤程式碼  
CLOSE corss_cursor   
DEALLOCATE corss_cursor RETURN 0 --釋放遊標,返回0表示成功  
end

輸出動態交叉表


DECLARE @RC int
DECLARE @strTabName varchar(50)
DECLARE @strCol varchar(50)
DECLARE @strGroup varchar(50)
DECLARE @strNumber varchar(50)
DECLARE @strSum varchar(10)
EXEC @RC = [db_Chapter5].[dbo].[Corss] DEFAULT, DEFAULT, DEFAULT, DEFAULT, DEFAULT
DECLARE @PrnLine nvarchar(4000)
PRINT '儲存過程: db_Chapter5.dbo.Corss'
SELECT @PrnLine = '	返回程式碼 = ' + CONVERT(nvarchar, @RC)
PRINT @PrnLine

二:使用遞迴的select變數,建立動態交叉表


DECLARE @strSql as varchar(1000) 

 select @strSql=isnull(@strSql, '')+char(13)+'   ,sum(case when [所在部門] = '''+[所在部門]+''' then [銷售業績] else null end) as ['+[所在部門]+']' 
  from (select distinct [所在部門] from 銷售) a  
SET @strsql ='select [員工姓名],sum([銷售業績]) as [ 銷售業績]  ' + @strSql + ' from 銷售 group by [員工姓名]'

exec(@strsql)

個人更喜歡使用方法二,執行速度相比較遊標很快,而且所需的程式碼量也少。