SQL Server2008 动态交叉表+字符串聚合

情景描述:因工作要求,需要做一个动态交叉表,这个比较简单,百度有很多案例,我是参考这篇文章一个动态交叉表的范例实现的。但存在一个问题,这个动态交叉表是使用聚合函数sum()+group by进行聚合的,聚合函数sum()只能对数值类型进行聚合,而我们需要对字符串型进行聚合,这就尴尬了,SQL Server2008又没有支持字符串型聚合的函数。

解决方案:先创建动态交叉表,然后再结合SQL字符串分组聚合实现。

解决步骤:1.创建动态交叉表(为了方便,这里直接在一个动态交叉表的范例该博文的基础上进行了修改)

--建立测试环境
set nocount on
create table test(model varchar(20),date int ,PlanDeliverQty int, DeliverQty int)
insert into test select 'a','8','10','10'
insert into test select 'a','10','50','60'
insert into test select 'b','8','100','100'
insert into test select 'b','9','200','200'
insert into test select 'b','10','100','110'
insert into test select 'c','10','200','220'
insert into test select 'd','10','300','330'
insert into test select 'e','11','250','240'
insert into test select 'e','12','100','99'
insert into test select 'f','12','150','140'
go
--测试

declare @sql varchar(max)
set @sql='select model,'
 select @sql=@sql+'sum(case when date='''+cast(date as varchar(10))+''' then PlanDeliverQty else 0 end)['+cast(date as varchar(10))+'],'
from (select distinct top 100 percent  date
 from test order by date)a

set @sql =left(@sql,len(@sql)-1)+' from test group by model'

exec(@sql)

 

--删除测试环境
drop table test
 set nocount off

 效果如下:

2.需要对字符串类型的数据进行聚合,以PlanDeliverQty | DeliverQty的效果显示在同一列,(这里为了方便就没有将PlanDeliverQty和DeliverQty转为PlanDeliverQty | DeliverQty形式的Varchar类型,而是直接把DeliverQty改成了Varchar类型,有需要转换的可以用临时表的方式转换),注:最好先了解:SQL字符串分组聚合

--建立测试环境
set nocount on
create table test(model varchar(20),date int ,PlanDeliverQty int, DeliverQty varchar(20))
insert into test select 'a','8','10','10|10'
insert into test select 'a','10','50','50|60'
insert into test select 'b','8','100','100|100'
insert into test select 'b','9','200','200|200'
insert into test select 'b','10','100','100|110'
insert into test select 'c','10','200','200|220'
insert into test select 'd','10','300','300|330'
insert into test select 'e','11','250','250|240'
insert into test select 'e','12','100','100|99'
insert into test select 'f','12','150','150|140'
go
--测试

declare @sql varchar(max)
set @sql = 'select model'
select @sql = @sql + ',''' + cast(date as varchar(10)) + '''=stuff((select '','' + [DeliverQty] from test T where T.model = B.model and T.date = ' + '''' 
			+ cast(date as varchar(10)) + '''' + ' for XML path('''')),1 , 1 , '''')'
					from (select distinct top 100 percent  date
						from test order by date) A
set @sql = @sql + ' from test B group by model'

exec(@sql) 
--删除测试环境
drop table test
 set nocount off
 

效果如下:

有疑问请留言!!

猜你喜欢

转载自blog.csdn.net/PErryiii/article/details/81539382