18、SQL提高篇(变量的使用 拓展)

例题用表:[cost]

18、SQL提高篇(变量的使用 拓展)_第1张图片

注:费用类型个数不定

将上图所示的表根据type列的类型转为下图样式

18、SQL提高篇(变量的使用 拓展)_第2张图片

*用变量将类型名分组动态提取的方法:

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方法,即为行列倒置。

 

你可能感兴趣的:(18、SQL提高篇(变量的使用 拓展))