SQL 动态行变列转换

来源:互联网 发布:面向对象程序设计java 编辑:程序博客网 时间:2024/06/10 22:13

  在SQL中有一类需求,需要行遍列。

   通用的方法是用 case when语句,但是如果行很多,或者行不定时,或者指标列很多,这种方法就无法适应。case when只适应于静态的行变列转换。
   Pivot方法能够同动态行变列,但还是有个缺点,只能出一个指标,比如demo的只有分数一个指标,假如还有多个指标的话,需要多个SQL拼接也倒是可行。

   

问题:

对于动态的转换有一个相对简单灵活的方法

问题:假设有张学生成绩表(tb)如下:

姓名 课程 分数
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94

想变成(得到如下结果): 
姓名 语文 数学 物理 
李四 74   84   94
张三 74   83   93


用静态的转换方法:

--SQL SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)declare @sql varchar(8000)set @sql = 'select 姓名 'select @sql = @sql + ' , max(case 课程 when ''' + 课程 + ''' then 分数 else 0 end) [' + 课程 + ']'from (select distinct 课程 from tb) as aset @sql = @sql + ' from tb group by 姓名'exec(@sql) --通过动态构建@sql,得到如下脚本select 姓名 as 姓名 ,  max(case 课程 when '语文' then 分数 else 0 end) 语文,  max(case 课程 when '数学' then 分数 else 0 end) 数学,  max(case 课程 when '物理' then 分数 else 0 end) 物理from tbgroup by 姓名--SQL SERVER 2005 动态SQL。declare @sql varchar(8000)select @sql = isnull(@sql + '],[' , '') + 课程 from tb group by 课程set @sql = '[' + @sql + ']'exec ('select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b')--得到SQL SERVER 2005 静态SQL。select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b
我的方法是:

if object_id('tempdb.dbo.#tmp_cmp')is not null drop table #tmp_cmpSelect [姓名] Into #tmp_cmp From tb group by [姓名]Declare @dim2 varchar(255)Declare Cur Cursor for Select [课程] From  tb  group by [课程]Open CurFetch next From Cur into @dim2 while @@FETCH_STATUS=0beginexec ( ' Alter table #tmp_cmp Add [分数_'+ @dim2 + '] int ') exec ( ' Update #tmp_cmp Set [分数_'+ @dim2 + '] =tlb.[分数]From #tmp_cmp tla inner Join tb tlb on tla.[姓名]=tlb.[姓名] where tlb.[课程]='''+@dim2+''' ') Fetch next From Cur into @dim2 EndClose CurDeallocate CurSelect * From #tmp_cmp 

这个方法写法不是很优雅,不过对付多指标的情况,还是比较方便的。





原创粉丝点击