sql server 建立動態交叉表
阿新 • • 發佈:2018-12-14
我所瞭解的建立動態交叉表有兩種方法,如下圖,有這樣一張銷售表 ,我想統計個人的銷售業績,如圖二表示出來,
建立銷售表
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)
個人更喜歡使用方法二,執行速度相比較遊標很快,而且所需的程式碼量也少。