一 例题
例题用表:[cost]
注:费用类型个数不定
将上图所示的表根据type列的类型转为下图样式
*用变量将类型名分组动态提取的方法:
1 declare @sql1 varchar(1000) 2 set @sql1='' 3 select @sql1= case @sql1 when '' then '' else @sql1+',' end +ltrim(str([type])) from cost group by [type] 4 select @sql1
查询的结果如下:
解法:
1、普通变量查询法:
--通过语句拼接实现--
1)声明变量
1 declare @sql nvarchar(max) 2 declare @sqlsumcol nvarchar(max) 3 declare @sqlcol nvarchar(max) 4 set @sqlsumcol = '' 5 set @sqlcol = ''
2)先查询出一个以"[类型x单价],[类型x用量],[类型x总价]"为列名的虚拟表结果集
1 select @sqlcol = case @sqlcol when '' then '' else @sqlcol + ',' end 2 + 'case when [type]=' + LTrim(Rtrim(STR([type]))) + ' then [price] else 0 end as [类型' + LTrim(Rtrim(STR([type]))) + '单价], ' 3 + 'case when [type]=' + LTrim(Rtrim(STR([type]))) + ' then [num] else 0 end as [类型' + LTrim(Rtrim(STR([type]))) + '用量], ' 4 + 'case when [type]=' + LTrim(Rtrim(STR([type]))) + ' then [all_price] else 0 end as [类型' + LTrim(Rtrim(STR([type]))) + '总价]' 5 from [cost] group by [type]
3)根据列名来进行分组求sum值等(因为单价不能求总和,所以用max来代替sum)
1 select @sqlsumcol = case @sqlsumcol when '' then '' else @sqlsumcol + ', ' end 2 + 'max([类型' + LTrim(Rtrim(STR([type]))) + '单价]) as [单价], ' 3 + 'sum([类型' + LTrim(Rtrim(STR([type]))) + '用量]) as [用量], ' 4 + 'sum([类型' + LTrim(Rtrim(STR([type]))) + '总价]) as [总价]' 5 from [cost] group by [type]
4)进行字符串拼接查询出总计以外的行
1 set @sql = '(select str([uid]) as [用户id], ' + @sqlsumcol + ' from 2 (select ' + Rtrim(@sqlcol) + ', [uid] from [cost] c inner join [user] u on c.[uid] = u.[id]) a 3 group by [uid])'
拼接上总计所需要的行
1 +'union (select ''总计'', ' + @sqlsumcol + ' from 2 (select ' + Rtrim(@sqlcol) + ', [uid] from [cost] c inner join [user] u on c.[uid] = u.[id]) a 3 )'
5)执行 exec(@sql)
2、2005以后的版本可以用PIVOT/UNPIVOT方法,即为行列倒置。
二、简单的例子:
select N'任务编号',missionid from MissionPool union select N'总和',SUM(case when MissionId=0 then 0 else missionid end) as id from MissionPool
这可以查询一列的数据,还有它的总和