sql中行列互换问题
2011-11-25 11:51
246 查看
感觉还是蛮全的
/*
标题:普通行列转换(version
2.0)
问题:假设有张学生成绩表(tb)如下:
姓名 课程
分数
张三 语文 74
张三
数学 83
张三
物理 93
李四 语文 74
李四
数学 84
李四
物理 94
想变成(得到如下结果):
姓名 语文
数学 物理
----
---- ---- ----
李四 74
84 94
张三
74 83 93
-------------------
*/
createtable tb(姓名 varchar(10)
, 课程 varchar(10)
, 分数 int)
insertinto tb values('张三' , '语文' , 74)
insertinto tb values('张三' , '数学' , 83)
insertinto tb values('张三' , '物理' , 93)
insertinto tb values('李四' , '语文' , 74)
insertinto tb values('李四' , '数学' , 84)
insertinto tb values('李四' , '物理' , 94)
go
--SQL
SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同)
select姓名 as姓名
,
max(case课程 when'语文'then分数 else0end) 语文,
max(case课程 when'数学'then分数 else0end) 数学,
max(case课程 when'物理'then分数 else0end) 物理
from tb
groupby姓名
--SQL
SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
declare@sqlvarchar(8000)
set@sql='select 姓名
'
select@sql=@sql+'
, max(case 课程
when '''+课程 +'''
then 分数
else 0 end) ['+课程 +']'
from (selectdistinct课程 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@sqlvarchar(8000)
select@sql=isnull(@sql+',' , '') +课程 from tb groupby课程
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分数 else0end) 语文,
max(case课程 when'数学'then分数 else0end) 数学,
max(case课程 when'物理'then分数 else0end) 物理,
cast(avg(分数*1.0) asdecimal(18,2)) 平均分,
sum(分数) 总分
from tb
groupby姓名
--SQL
SERVER 2000 动态SQL。
declare@sqlvarchar(8000)
set@sql='select 姓名
'
select@sql=@sql+'
, max(case 课程
when '''+课程 +'''
then 分数
else 0 end) ['+课程 +']'
from (selectdistinct课程 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) asdecimal(18,2)) 平均分
, sum(分数) 总分 from tb groupby姓名)
n
where m.姓名 = n.姓名
--SQL
SERVER 2005 动态SQL。
declare@sqlvarchar(8000)
select@sql=isnull(@sql+',' , '') +课程 from tb groupby课程
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.姓名')
droptable tb
------------------
------------------
/*
问题:如果上述两表互相换一下:即表结构和数据为:
姓名 语文
数学 物理
张三 74 83 93
李四 74 84 94
想变成(得到如下结果):
姓名 课程
分数
----
---- ----
李四 语文 74
李四
数学 84
李四
物理 94
张三 语文 74
张三
数学 83
张三
物理 93
--------------
*/
createtable tb(姓名 varchar(10)
, 语文 int , 数学 int , 物理 int)
insertinto tb values('张三',74,83,93)
insertinto tb values('李四',74,84,94)
go
--SQL
SERVER 2000 静态SQL。
select*from
(
select姓名
, 课程 ='语文' , 分数 =语文 from tb
unionall
select姓名
, 课程 ='数学' , 分数 =数学 from tb
unionall
select姓名
, 课程 ='物理' , 分数 =物理 from tb
) t
orderby姓名
, case课程 when'语文'then1when'数学'then2when'物理'then3end
--SQL
SERVER 2000 动态SQL。
--调用系统表动态生态。
declare@sqlvarchar(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,不包含列名为姓名的其它列
orderby 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
unionall
select姓名 as姓名
, 课程 ='数学' , 分数 =数学 from tb
unionall
select姓名 as姓名
, 课程 ='物理' , 分数 =物理 from tb
unionall
select姓名 as姓名
, 课程 ='平均分' , 分数 =cast((语文 +数学 +物理)*1.0/3asdecimal(18,2)) from tb
unionall
select姓名 as姓名
, 课程 ='总分' , 分数 =语文 +数学 +物理 from tb
) t
orderby姓名
, case课程 when'语文'then1when'数学'then2when'物理'then3when'平均分'then4when'总分'then5end
droptable tb
/*
标题:普通行列转换(version
2.0)
问题:假设有张学生成绩表(tb)如下:
姓名 课程
分数
张三 语文 74
张三
数学 83
张三
物理 93
李四 语文 74
李四
数学 84
李四
物理 94
想变成(得到如下结果):
姓名 语文
数学 物理
----
---- ---- ----
李四 74
84 94
张三
74 83 93
-------------------
*/
createtable tb(姓名 varchar(10)
, 课程 varchar(10)
, 分数 int)
insertinto tb values('张三' , '语文' , 74)
insertinto tb values('张三' , '数学' , 83)
insertinto tb values('张三' , '物理' , 93)
insertinto tb values('李四' , '语文' , 74)
insertinto tb values('李四' , '数学' , 84)
insertinto tb values('李四' , '物理' , 94)
go
--SQL
SERVER 2000 静态SQL,指课程只有语文、数学、物理这三门课程。(以下同)
select姓名 as姓名
,
max(case课程 when'语文'then分数 else0end) 语文,
max(case课程 when'数学'then分数 else0end) 数学,
max(case课程 when'物理'then分数 else0end) 物理
from tb
groupby姓名
--SQL
SERVER 2000 动态SQL,指课程不止语文、数学、物理这三门课程。(以下同)
declare@sqlvarchar(8000)
set@sql='select 姓名
'
select@sql=@sql+'
, max(case 课程
when '''+课程 +'''
then 分数
else 0 end) ['+课程 +']'
from (selectdistinct课程 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@sqlvarchar(8000)
select@sql=isnull(@sql+',' , '') +课程 from tb groupby课程
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分数 else0end) 语文,
max(case课程 when'数学'then分数 else0end) 数学,
max(case课程 when'物理'then分数 else0end) 物理,
cast(avg(分数*1.0) asdecimal(18,2)) 平均分,
sum(分数) 总分
from tb
groupby姓名
--SQL
SERVER 2000 动态SQL。
declare@sqlvarchar(8000)
set@sql='select 姓名
'
select@sql=@sql+'
, max(case 课程
when '''+课程 +'''
then 分数
else 0 end) ['+课程 +']'
from (selectdistinct课程 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) asdecimal(18,2)) 平均分
, sum(分数) 总分 from tb groupby姓名)
n
where m.姓名 = n.姓名
--SQL
SERVER 2005 动态SQL。
declare@sqlvarchar(8000)
select@sql=isnull(@sql+',' , '') +课程 from tb groupby课程
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.姓名')
droptable tb
------------------
------------------
/*
问题:如果上述两表互相换一下:即表结构和数据为:
姓名 语文
数学 物理
张三 74 83 93
李四 74 84 94
想变成(得到如下结果):
姓名 课程
分数
----
---- ----
李四 语文 74
李四
数学 84
李四
物理 94
张三 语文 74
张三
数学 83
张三
物理 93
--------------
*/
createtable tb(姓名 varchar(10)
, 语文 int , 数学 int , 物理 int)
insertinto tb values('张三',74,83,93)
insertinto tb values('李四',74,84,94)
go
--SQL
SERVER 2000 静态SQL。
select*from
(
select姓名
, 课程 ='语文' , 分数 =语文 from tb
unionall
select姓名
, 课程 ='数学' , 分数 =数学 from tb
unionall
select姓名
, 课程 ='物理' , 分数 =物理 from tb
) t
orderby姓名
, case课程 when'语文'then1when'数学'then2when'物理'then3end
--SQL
SERVER 2000 动态SQL。
--调用系统表动态生态。
declare@sqlvarchar(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,不包含列名为姓名的其它列
orderby 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
unionall
select姓名 as姓名
, 课程 ='数学' , 分数 =数学 from tb
unionall
select姓名 as姓名
, 课程 ='物理' , 分数 =物理 from tb
unionall
select姓名 as姓名
, 课程 ='平均分' , 分数 =cast((语文 +数学 +物理)*1.0/3asdecimal(18,2)) from tb
unionall
select姓名 as姓名
, 课程 ='总分' , 分数 =语文 +数学 +物理 from tb
) t
orderby姓名
, case课程 when'语文'then1when'数学'then2when'物理'then3when'平均分'then4when'总分'then5end
droptable tb
相关文章推荐
- sql行列互换问题
- sql行列互换
- 行列互换的SQL
- 一个SQL语句的问题:行列转换
- 矩阵的转化问题【行列互换】(稀疏矩阵)
- 一道SQL面试题(行列互换)
- 一道SQL面试题(行列互换)
- SQL 面试经典问题 行列互相转化
- sql行列转换问题 .
- 矩阵的转化问题【行列互换】(稀疏矩阵)
- MS-SQLServer 2000 T-SQL 交叉报表(行列互换) 交叉查询 旋转查询
- 一道SQL面试题(行列互换)
- sql查询 竖排变横排及横排变竖排显示 行列转换问题
- 一道SQL面试题(行列互换)
- 一个SQL语句的问题:行列转换
- SQL行列互换
- SQL延伸2-最简单的行列互换
- MS-SQLServer 2000 T-SQL 交叉报表(行列互换) 交叉查询 旋转查询
- 今天在csdn上遇到一个问题,是关于sql数据行列转换的,我的写法如下:
- SQL 行列互换 PIVOT【转载】