行列转换/矩阵转换

                行列转换/矩阵转换

一、行列转换。
1、纵转换为横。
有表:test(name char(10),km char(10),cj int)
name  km  cj
----------------------------------------------
张三  语文  80
张三  数学  86
张三  英语  75
李四  语文  78
李四  数学  85
李四  英语  78

要求以横向格式显示,即:
想变成

姓名   语文   数学   英语
----------------------------
张三   80     86     75
李四   78     85     78

Create table test (name char(10),km char(10),cj int)
go
insert test values('张三','语文',80)
insert test values('张三','数学',86)
insert test values('张三','英语',75)
insert test values('李四','语文',78)
insert test values('李四','数学',85)
insert test values('李四','英语',78)

方法一:
select 姓名=name,语文=sum(case km when '语文' then cj else 0 end),数学=sum(case km when '数学' then cj else 0 end)
 ,英语=sum(case km when '英语' then cj else 0 end)
from test group by name
解析:此方法简单易懂,但列名与列数固定,不够灵活。
方法二:
declare @sql varchar(8000)
set @sql = 'select name'
select @sql = @sql + ',sum(case km when '''+km+''' then cj end) ['+km+']'
 from (select distinct km from test) as a
select @sql = @sql+' from test group by name'
exec(@sql)

drop table test

解析:此方法结构稍复杂,但通用性好,在列数不固定时能体现出它的优点。

二、横转换为纵

有表 unknown
name a c b d
Tom 1 2 3 4
Sun 1 2 3 4
要求以纵向格式显示
name km value
tom a 1
tom c 2
tom b 3
tom d 4
sun a 1
sun c 2
sun b 3
sun d 4
test:
create table unknown(name char(4),a int,c int,b int,d int)
insert unknown(name,a,c,b,d)
select 'a',1,2,3,4
union all select 'b',5,6,7,8
union all select 'c',9,10,11,12
union all select 'd',13,14,15,16
1.
select * from (
select name,'a' as item,a as value from unknown
union all
select name,'b' as item,b as value from unknown
union all
select name,'c' as item,c as value from unknown
union all
select name,'d' as item,d as value from unknown
)tmp
order by name,item

2.排序按列的顺序
select * from (
select name,'a' as item,a as value from unknown
union all
select name,'b' as item,b as value from unknown
union all
select name,'c' as item,c as value from unknown
union all
select name,'d' as item,d as value from unknown
)tmp
order by name,charindex(item,'acbd')
或使用系统表
select view1.* from
(
select name,'a' as item,a as value from unknown
union all
select name,'b' as item,b as value from unknown
union all
select name,'c' as item,c as value from unknown
union all
select name,'d' as item,d as value from unknown
) view1 ,
syscolumns s
where view1.item *= s.name and id=object_id('unknown')
order by view1.name,s.colid
或者
select a.name,item=b.name,value=(case b.name when 'a' then a when 'b' then b when 'c' then c else d end)
from unknown a,syscolumns b where b.id=object_id('unknown') and b.name<>'name' order by a.name,b.colid
当列比较多时可以这样
declare @sql varchar(8000)
set @sql = 'select a.name,item=b.name,value=sum(case b.name '
select @sql = @sql + ' when '''+name+''' then '+name
 from (select distinct name from syscolumns where id=object_id('unknown') and name<>'name') as a
select @sql = @sql+' end) from unknown a,syscolumns b where id=object_id(''unknown'') and b.name<>''name'' group by a.name,b.name,b.colid order by a.name,b.colid'
select @sql
exec(@sql)

二、矩阵转置
有表 unknown
nam a c b d
--------------------------------------
Tom 1 2 3 4
Sun 5 6 7 8
mon 9 10 11 12
das 13 14 15 16
hor 17 18 19 20

要求以纵向格式显示
name col1 col2 col3 col4 col5
----------------------------------------------
nam tom sun mon das hor
a 1 5 9 13 17
c 2 6 10 14 18
b 3 7 11 15 19
d 4 8 12 16 20
方法一:使用循环。
create table test(nam varchar(4),a int,c int,b int,d int)
insert test(nam,a,c,b,d)
    select 'Tom',     1,     2,     3,     4
union all select 'Sun' ,    5 ,    6 ,    7 ,    8
union all select 'mon'  ,   9  ,   10 ,    11,     12
union all select 'das'   ,  13  ,   14 ,    15,     16
union all select 'hor'    , 17   ,  18  ,   19 ,    20

create proc proc_sky_blue (@tablename varchar(200))
as
begin
  set nocount on
  declare @col nvarchar(256)
  declare @makesql nvarchar(4000)
  declare @insertsql nvarchar(4000)
  declare @caculatesql nvarchar(400)
  declare @count int
  declare @i int
  create table #tmp (colname nvarchar(20))
  select @caculatesql = 'select @count=count(1) from ' + @tablename
  exec sp_executesql @caculatesql,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值