+ -
当前位置:首页 → 问答吧 → sql 行转列

sql 行转列

时间:2011-10-25

来源:互联网

将下表数据: 
A b c d e  
-------------------- ----------- ----------- ----------- -----------  
x 1 2 3 4 
y 5 6 7 8 
z 9 10 11 12 
  
转化成如下结果: 
x y z
1 5 9 
2 6 10 
3 7 11 
4 8 12 

作者: jisg_57   发布时间: 2011-10-25

如果是SQL SERVER可参考如下存储过程.oracel不知道.
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      320      330
工资      100      110      120      130
福利      200      210      220      230

(所影响的行数为 3 行)
*/



SQL code

--SQL2005静态写法
--创建测试数据
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

SELECT * FROM 
(
  SELECT 考核月份,月份,金额 FROM 
     (SELECT 月份, 工资, 福利, 奖金 FROM Test) p
  UNPIVOT
     (金额 FOR 考核月份 IN (工资, 福利, 奖金))AS unpvt
) T
PIVOT
(MAX(金额) FOR 月份 in ([1月],[2月],[3月],[4月]))AS pt

drop table test

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

(3 行受影响)
*/


作者: dawugui   发布时间: 2011-10-25

顶楼上,有分接么?

作者: yinan9   发布时间: 2011-10-25

oracle
http://topic.csdn.net/u/20100109/13/6a10c168-f190-4766-b838-adbf03c4ac7b.html?13274

作者: roy_88   发布时间: 2011-10-25