1. 程式人生 > >SQL生成動態交叉表+字串聚合

SQL生成動態交叉表+字串聚合

情景描述:因工作要求,需要做一個動態交叉表,這個比較簡單,百度有很多案例,我是參考這篇文章一個動態交叉表的範例實現的。但存在一個問題,這個動態交叉表是使用聚合函式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 @
[email protected]
+'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
 

效果如下:

有疑問請留言!!