sql 行列转换

原创 2008年09月28日 16:41:00
 我有这样的一张表(a):
s_id   s_name   sms_days  s_state  s_order  
------ -------- --------- -------- -------- 
1      步骤一      3         0        1
2      步骤二      3         0        2
3      步骤三      3         0        3
4      步骤四      5         0        4
这里的s_name 的行数和内容是不确定的,s_id是自动增加的主键.s_order是指优先级.

我用这样的sql语句把行变成列
declare @sql varchar(8000)
set @sql='select ' 
select  @sql=@sql+'max(case s_name when '''+ s_name +''' then s_id end) '+ s_name +' ,'
from (select distinct s_name from step_1)  a
set @sql=left(@sql,len(@sql)-1)
--print @sql
set @sql=@sql+'  from step_1'
exec(@sql)
得到结果是(b):
步骤二   步骤三   步骤四  步骤一
------- -------- ------  ---    
2       3        4       1  

但是我想得到是(c):
步骤一     步骤二   步骤三   步骤四  
---     ------- -------- ------   
1       2       3        4        
就是新组成的查询表(b)的列按表(a)中s_order的优先级从小到大的排列,
得到表(c)的样子   

另外我还想把这个查询出来的建成一个视图,请csdn高手达人给出相应的sql
100  修改 删除 举报 引用 回复 这个问题第1个回答:
SQL code
/*

标题:普通行列转换(version 2.0)

作者:爱新觉罗.毓华

时间:2008-03-09

地点:广东深圳

说明:普通行列转换(version 1.0)仅针对sql server 2000提供静态和动态写法,version 2.0增加sql server 2005的有关写法。



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

姓名 课程 分数

张三 语文 74

张三 数学 83

张三 物理 93

李四 语文 74

李四 数学 84

李四 物理 94

想变成(得到如下结果):

姓名 语文 数学 物理

---- ---- ---- ----

李四 74 84 94

张三 74 83 93

-------------------

*/



create table tb(姓名 varchar(10) , 课程 varchar(10) , 分数 int)

insert into tb values('张三' , '语文' , 74)

insert into tb values('张三' , '数学' , 83)

insert into tb values('张三' , '物理' , 93)

insert into tb values('李四' , '语文' , 74)

insert into tb values('李四' , '数学' , 84)

insert into tb values('李四' , '物理' , 94)

go



--SQL SERVER 2000 静态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 tb

group by 姓名



--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 a

set @sql = @sql + ' from tb group by 姓名'

exec(@sql)



--SQL SERVER 2005 静态SQL。

select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b



--SQL SERVER 2005 动态SQL。

declare @sql varchar(8000)

select @sql = isnull(@sql + ',' , '') + 课程 from tb group by 课程

exec ('select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b')



---------------------------------



/*

问题:在上述结果的基础上加平均分,总分,得到如下结果:

姓名 语文 数学 物理 平均分 总分

---- ---- ---- ---- ------ ----

李四 74 84 94 84.00 252

张三 74 83 93 83.33 250

*/



--SQL SERVER 2000 静态SQL。

select 姓名 姓名,

max(case 课程 when '语文' then 分数 else 0 end) 语文,

max(case 课程 when '数学' then 分数 else 0 end) 数学,

max(case 课程 when '物理' then 分数 else 0 end) 物理,

cast(avg(分数*1.0) as decimal(18,2)) 平均分,

sum(分数) 总分

from tb

group by 姓名



--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 a

set @sql = @sql + ' , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名'

exec(@sql)



--SQL SERVER 2005 静态SQL。

select m.* , n.平均分 , n.总分 from

(select * from (select * from tb) a pivot (max(分数) for 课程 in (语文,数学,物理)) b) m,

(select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n

where m.姓名 = n.姓名



--SQL SERVER 2005 动态SQL。

declare @sql varchar(8000)

select @sql = isnull(@sql + ',' , '') + 课程 from tb group by 课程

exec ('select m.* , n.平均分 , n.总分 from

(select * from (select * from tb) a pivot (max(分数) for 课程 in (' + @sql + ')) b) m ,

(select 姓名 , cast(avg(分数*1.0) as decimal(18,2)) 平均分 , sum(分数) 总分 from tb group by 姓名) n

where m.姓名 = n.姓名')



drop table tb



------------------

------------------



/*

问题:如果上述两表互相换一下:即表结构和数据为:

姓名 语文 数学 物理

张三 74  83  93

李四 74  84  94

想变成(得到如下结果):

姓名 课程 分数

---- ---- ----

李四 语文 74

李四 数学 84

李四 物理 94

张三 语文 74

张三 数学 83

张三 物理 93

--------------

*/



create table tb(姓名 varchar(10) , 语文 int , 数学 int , 物理 int)

insert into tb values('张三',74,83,93)

insert into tb values('李四',74,84,94)

go



--SQL SERVER 2000 静态SQL。

select * from

(

select 姓名 , 课程 = '语文' , 分数 = 语文 from tb

union all

select 姓名 , 课程 = '数学' , 分数 = 数学 from tb

union all

select 姓名 , 课程 = '物理' , 分数 = 物理 from tb

) t

order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 end



--SQL SERVER 2000 动态SQL。

--调用系统表动态生态。

declare @sql varchar(8000)

select @sql = isnull(@sql + ' union all ' , '' ) + ' select 姓名 , [课程] = ' + quotename(Name , '''') + ' , [分数] = ' + quotename(Name) + ' from tb'

from syscolumns

where name! =
N'姓名' and ID = object_id('tb') --表名tb,不包含列名为姓名的其它列

order by colid asc

exec(@sql + ' order by 姓名 ')



--SQL SERVER 2005 动态SQL。

select 姓名 , 课程 , 分数 from tb unpivot (分数 for 课程 in([语文] , [数学] , [物理])) t



--SQL SERVER 2005 动态SQL,同SQL SERVER 2000 动态SQL。



--------------------

/*

问题:在上述的结果上加个平均分,总分,得到如下结果:

姓名 课程 分数

---- ------ ------

李四 语文 74.00

李四 数学 84.00

李四 物理 94.00

李四 平均分 84.00

李四 总分 252.00

张三 语文 74.00

张三 数学 83.00

张三 物理 93.00

张三 平均分 83.33

张三 总分 250.00

------------------

*/



select * from

(

select 姓名 as 姓名 , 课程 = '语文' , 分数 = 语文 from tb

union all

select 姓名 as 姓名 , 课程 = '数学' , 分数 = 数学 from tb

union all

select 姓名 as 姓名 , 课程 = '物理' , 分数 = 物理 from tb

union all

select 姓名 as 姓名 , 课程 = '平均分' , 分数 = cast((语文 + 数学 + 物理)*1.0/3 as decimal(18,2)) from tb

union all

select 姓名 as 姓名 , 课程 = '总分' , 分数 = 语文 + 数学 + 物理 from tb

) t

order by 姓名 , case 课程 when '语文' then 1 when '数学' then 2 when '物理' then 3 when '平均分' then 4 when '总分' then 5 end



drop table tb








    

sql实现行列转换

postgresql 现有一个表如(表一)想要转换为(表二) sql:select stuName as 姓名,chinese as 语文,math as 数学,english as 英文 from...
  • ECHOutopia
  • ECHOutopia
  • 2014年10月28日 11:02
  • 2854

[数据库] SQL查询语句表行列转换及一行数据转换成两列

本文主要讲述了SQL查询语句表之间的行列转换,同时也包括如何将一行数据转换成两列数据的方法、子查询的应用、decode函数的用法。希望文章对你有所帮助~ 1.创建数据库表及插入数据 2.子查询统计不同...
  • Eastmount
  • Eastmount
  • 2016年01月22日 05:03
  • 17099

锋利的SQL-SQL Server的表旋转(行列转换)

所谓表旋转,就是将表的行转换为列,或是将表的列转换为行,这是从SQL Server 2005开始提供的新技术。因此,如果希望使用此功能,需要将数据库的兼容级别设置为90。表旋转在某些方面也是解决了表的...
  • zhanghongju
  • zhanghongju
  • 2014年08月17日 18:37
  • 4918

数据库中的行列转换(横竖转换)

(竖的数据表变横的数据表)例子: SELECT NAME, SUM(DECODE(course,'JDBC',gradem,0)) JDBC, SUM(DECODE(course,'Hibernate...
  • secretkevin
  • secretkevin
  • 2016年01月15日 11:41
  • 5145

T-SQL查询:行列转换简单实例

--★转换结果如上图 --创建测试标 CREATE TABLE [成绩表]( [编号] [int] IDENTITY(1,1) NOT NULL, [姓名] [varchar](50) NU...
  • kk185800961
  • kk185800961
  • 2013年01月07日 18:11
  • 2140

Sql实现行列转换

从MS Sql Server 2005微软就推出了pivot和unpivot实现行列转换,这极大的方便了我们存储数据和呈现数据。今天就对这两个关键字进行分析,结合实例讲解如何存储数据,如何呈现数据。...
  • dotnetstudio
  • dotnetstudio
  • 2013年08月06日 14:13
  • 6833

行列转换-->动态SQL语句例子

1. 例子create table cjb(姓名 char (10),课程名 char (10),成绩 [decimal](12, 2))insert into cjb  select 张,    数...
  • hdhai9451
  • hdhai9451
  • 2009年12月17日 18:03
  • 2821

SQL 2008行列转换的pivot--产生动态列

 突然间发现,已经好久没有写博客了,也好久没用SQLServer进行开发了。由于目前项目开发的原因,对于SQL Server才重视起来。发现SQL Server也引进了不少新的东西,现将一个不错...
  • langcai1981
  • langcai1981
  • 2014年01月21日 10:42
  • 7964

SQL中关于case关键字的例子(行列转换)

case关键字用法类似于C#、Java中的switch...case...的用法: select name, ( case express --列名(表达式) when... then......
  • qingYun1029
  • qingYun1029
  • 2011年02月19日 19:57
  • 2388

sql server行列转化和行列置换

行列转换:姓名 课程 分数 张三 语文 74 张三 数学 83 张三 物理 93 李四 语文 74 李四 数学 84 李四 物理 94 想变成(得到如下结果): 姓名 语文 数学...
  • yubofighting
  • yubofighting
  • 2011年09月11日 14:16
  • 5980
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:sql 行列转换
举报原因:
原因补充:

(最多只允许输入30个字)