/*-- 数据测试环境 --*/
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