行列转换/矩阵转换

                行列转换/矩阵转换

一、行列转换。
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,

你可能感兴趣的:(行列转换/矩阵转换)