動態交叉表

來源:互聯網
上載者:User

/*-- 資料測試環境 --*/
if exists (select * from dbo.sysobjects where id = object_id(N'[tb]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [tb]
GO

create table tb(單位名稱 varchar(10),日期 datetime,銷售額 int)
insert into tb
 select 'A單位','2001-01-01',100
 union all select 'B單位','2001-01-02',101
 union all select 'C單位','2001-01-03',102
 union all select 'D單位','2001-01-04',103
 union all select 'E單位','2001-01-05',104
 union all select 'F單位','2001-01-06',105
 union all select 'G單位','2001-01-07',106
 union all select 'H單位','2001-01-08',107
 union all select 'I單位','2001-01-09',108
 union all select 'J單位','2001-01-11',109

/*-- 要求結果
日期       A單位  B單位 C單位 D單位 E單位  F單位 G單位 H單位 I單位 J單位  
---------- ----- ----- ----- ----- ----- ----- ----  ----  ---- ------
2001-01-01 100   0     0     0     0     0     0     0     0     0
2001-01-02 0     101   0     0     0     0     0     0     0     0
2001-01-03 0     0     102   0     0     0     0     0     0     0
2001-01-04 0     0     0     103   0     0     0     0     0     0
2001-01-05 0     0     0     0     104   0     0     0     0     0
2001-01-06 0     0     0     0     0     105   0     0     0     0
2001-01-07 0     0     0     0     0     0     106   0     0     0
2001-01-08 0     0     0     0     0     0     0     107   0     0
2001-01-09 0     0     0     0     0     0     0     0     108   0
2001-01-11 0     0     0     0     0     0     0     0     0     109
--*/


declare @sql varchar(8000)
set @sql='select 日期=convert(varchar(10),日期,120)'
select @sql=@sql+',['+單位名稱
 +']=sum(case 單位名稱 when '''+單位名稱+''' then 銷售額 else 0 end)'
from(select distinct 單位名稱 from tb) a
exec(@sql+' from tb group by convert(varchar(10),日期,120)') 

該方法有個缺陷,@sql varchar(8000)能裝下的字元總量是有限的,若select distinct 單位名稱 from tb

產生的結果集很多,會導致@sql的字元長度超出8000

-------------------------------用遊標來做

原資料表

id    員工姓名  所在部門   銷售業績

...    ......            服裝部       ........

效果表

員工姓名  銷售業績(合計)   服裝部  家電部 ......

                  9                            4             6

create procedure Cross

@strTabName as varchar(50)='銷售',

@strCol as varchar(50)='所在部門',

@strGroup as varchar(50)='員工姓名',  //分組欄位

@strNumber as varchar(50)='銷售業績' ,//被統計欄位

@strSum as varchar(50)='Sum' //運算方式

as

declare @strSql as varchar(1000),@strTmpCol as varchar(100)

EXECUTE('DECLARE cross_cursor CURSOR FOR SELECT DISTINCT'+@strCol+'from'+@strTabName+' for read only') --產生遊標

begin

SET nocount ON

SET @strsql='select'+@strGroup+','+@strSum+'('+@strNumber+') as ['+@strNumber+']'  //查詢的前半段

OPEN cross_cursor

while(0=0)

BEGIN

FETCH NEXT FROM cross_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   //查詢結尾

EXCUTE(@strsql)     --執行

if @@error<>0 RETURN @@error    //如果出錯,返回錯誤碼

CLOSE cross_cursor

DEALLOCATE cross_cursor RETURN 0  //釋放遊標,返回0表示成功

end

go

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.