日期:2014-05-18  浏览次数:20386 次

SQL 动态行转列
现有一张【Hong_lvnew】表,
表中的列为【regtime,lv1,lv2,lv3 ,lv4 ,lv5 ,lv6, lv7, lv8,lv9 ,lv10, lv11,lv12 , lv13, lv14 ,lv15】  
表中的数据为:
  regtime lv1 lv2 lv3 lv4 lv5 lv6 lv7 lv8 lv9 lv10 lv11 lv12 lv13 lv14 lv15
  2011-11-07 122 112 116 491 468 753 692 187 922 439 421 247 668 632 119
  2011-08-23 433 449 226 491 468 753 692 187 922 439 421 247 668 632 119  
  2011-06-06 111 559 336 491 468 753 692 187 922 439 421 247 668 632 119
  2011-02-14 222 330 446 491 468 753 692 187 922 439 421 247 668 632 119
  2011-12-19 333 449 556 491 468 753 692 187 922 439 421 247 668 632 119
  .......

现在我需要得到的结果格式为:

  分布等级 2011-11-07 2011-08-23 2011-06-06 2011-02-14 2011-12-19
  lv1 122 433 111 222 333
  lv2 112 449 559 330 449
  lv3 116 226 336 446 556
  lv4 491 491 491 491 491
  lv5 468 468 468 468 468
  lv6 753 753 753 753 753
  lv7 692 922 922 922 922  
  ..........

------解决方案--------------------
Hong_lvnew 表中要是有上万的数据,结果中就要有上万的列?
SQL SERVER 2005的列数上限貌似是1024
------解决方案--------------------
表的列是有限制的。
------解决方案--------------------
参考这个,特别是后面那个存储过程.

/*
标题:90度旋转行列转换之一
作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
时间:2010-05-08
地点:重庆航天职业学院
说明:无
*/
/*
数据库中tb表格如下
月份 工资 福利 奖金
1月 100 200 300
2月 110 210 310
3月 120 220 320
4月 130 230 330

我想得到的结果是

项目 1月 2月 3月 4月
工资 100 110 120 130
福利 200 210 220 230
奖金 300 310 320 330

就是说完全把表格的行列颠倒,有点像那种旋转矩阵,请问如何用sql 语句实现?
*/

SQL code

/*--行列互换的通用存储过程(原著:邹建):将指定的表,按指定的字段进行行列互换*/
create proc p_zj
       @tbname sysname, --要处理的表名
       @fdname sysname, --做为转换的列名
       @new_fdname sysname='' --为转换后的列指定列名
as
declare @s1 varchar(8000) , @s2 varchar(8000),
        @s3 varchar(8000) , @s4 varchar(8000),
        @s5 varchar(8000) , @i varchar(10)
select @s1 = '' , @s2 = '' , @s3 = '' , @s4 = '' , @s5 = '' , @i = '0'
select @s1 = @s1 + ',@' + @i + ' varchar(8000)',
       @s2 = @s2 + ',@' + @i + '=''' + case isnull(@new_fdname , '') when '' then ''
       else @new_fdname + '=' end + '''''' + name + '''''''',
       @s3 = @s3 + 'select @' + @i + '=@' + @i + '+'',['' + [' + @fdname + 
       ']+'']=''+cast([' + name + '] as varchar) from [' + @tbname + ']',
       @s4 = @s4 + ',@' + @i + '=''select ''+@' + @i,
       @s5 = @s5 + '+'' union all ''+@' + @i,
       @i=cast(@i as int)+1
from syscolumns
where object_id(@tbname)=id and name<>@fdname

select @s1=substring(@s1,2,8000),
       @s2=substring(@s2,2,8000),
       @s4=substring(@s4,2,8000),
       @s5=substring(@s5,16,8000)
exec('declare ' + @s1 + 'select ' + @s2 + @s3 + 'select ' + @s4 + '
exec(' + @s5 + ')')
go

--创建测试数据
create table Test(月份 varchar(4), 工资 int, 福利 int, 奖金 int)
insert Test 
select '1月',100,200,300 union all
select '2月',110,210,310 union all
select '3月',120,220,320 union all
select '4月',130,230,330
go

--用上面的存储过程测试:
exec p_zj 'Test', '月份' , '项目'

drop table Test
drop proc p_zj

/*
项目      1月      2月      3月      4月
--------  ------   -------- -------- --------
奖金      300      310