/*-- 資料測試環境 --*/
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