求一条竖转横的sql语句!在线等待..急!

yangzong18 2008-11-12 10:45:27
我想把以下表的数据转成横项的,该如何转???

A1 A2 A3 A4 A5

2006级期末考 20080101 张三 语文 101
2006级期末考 20080202 李四 语文 109
2006级期末考 20080303 王五 语文 100
2006级期末考 20080101 张三 数学 101
2006级期末考 20080202 李四 数学 85
2006级期末考 20080303 王五 数学 58
2006级期末考 20080101 张三 政治 56
2006级期末考 20080202 李四 政治 56
2006级期末考 20080303 王五 政治 50

我想把以上的表转成



考试项目 学号 姓名 语文 数学 政治

2006级期末考 20080101 张三 101 101 56
2006级期末考 20080202 李四 109 85 56
2006级期末考 20080303 王五 100 58 50

但注意的是科目是不固定的也就是说如果他再增加科目的时候而横项也会自动增加

例如,如果加了英语

A1 A2 A3 A4 A5

2006级期末考 20080101 张三 语文 101
2006级期末考 20080202 李四 语文 109
2006级期末考 20080303 王五 语文 100
2006级期末考 20080101 张三 数学 101
2006级期末考 20080202 李四 数学 85
2006级期末考 20080303 王五 数学 58
2006级期末考 20080101 张三 政治 56
2006级期末考 20080202 李四 政治 56
2006级期末考 20080303 王五 政治 50
2006级期末考 20080101 张三 英语 102
2006级期末考 20080202 李四 英语 110
2006级期末考 20080303 王五 英语 93

那么就应该变为


考试项目 学号 姓名 语文 数学 政治 英语

2006级期末考 20080101 张三 101 101 56 102
2006级期末考 20080202 李四 109 85 56 110
2006级期末考 20080303 王五 100 58 50 93


我该如何转呢?请各位大哥帮帮忙小弟急用,万分感谢!
...全文
559 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
jinjazz 2008-11-12
  • 打赏
  • 举报
回复
我对你的理解能力很无语,自己琢磨吧...
yangzong18 2008-11-12
  • 打赏
  • 举报
回复
to jinjazz

我建立好临时表后在sql server 2000里执行了下面代码,但他只提示影响了一条上次查询但没有返回查询结果这是为何
declare @sql varchar(8000)
set @sql='select A1,A2,A3'
select @sql=@sql+',sum(case when A4='''+A4+''' then A5 else 0 end)['+A4+']' from
(select distinct A4 from test)a
set @sql=@sql+' from test group by A1,A2,A3 order by A1,A2,A3'

exec(@sql)

还有我把上面的改成了sql语句但他说from附近有错误这是为何!
select A1,A2,A3,sum(case when A4='+A4+' then A5 else 0 end)[+A4+] from
(select distinct A4 from test)a from test group by A1,A2,A3 order by A1,A2,A3

麻烦各位大哥帮看看,谢谢!
火龙岛主 2008-11-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 yf520gn 的回复:]
引用 4 楼 yangzong18 的回复:
呵,各位大哥!可能是我没说明白!

科目是不固定的也就是说有可能是三科,也就可能是四科或五科!所以说应该不能用 课程 = '语文' 或 课程 = '数学'
这样的方法来写,如果这样写就写死了!应该如转呢?麻烦各位再帮我想想办法,小弟万分感谢!
你仔细看我的帖子了吗?
[/Quote]
楼主没看清楚,也没有贴代码在查询分析器里试,
yf520gn的是动态的SQL语句。SQL2005都帮你写好了。呵呵!
yf520gn 2008-11-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 yangzong18 的回复:]
呵,各位大哥!可能是我没说明白!

科目是不固定的也就是说有可能是三科,也就可能是四科或五科!所以说应该不能用 课程 = '语文' 或 课程 = '数学'
这样的方法来写,如果这样写就写死了!应该如转呢?麻烦各位再帮我想想办法,小弟万分感谢!
[/Quote]你仔细看我的帖子了吗?
yangzong18 2008-11-12
  • 打赏
  • 举报
回复
呵,各位大哥!可能是我没说明白!

科目是不固定的也就是说有可能是三科,也就可能是四科或五科!所以说应该不能用 课程 = '语文' 或 课程 = '数学'
这样的方法来写,如果这样写就写死了!应该如转呢?麻烦各位再帮我想想办法,小弟万分感谢!
jinjazz 2008-11-12
  • 打赏
  • 举报
回复
--建立测试环境
set nocount on
create table test(A1 varchar(20),A2 varchar(20),A3 varchar(20),A4 varchar(20),A5 float)
insert into test select '2006级期末考','20080101','张三','语文','101'
insert into test select '2006级期末考','20080202','李四','语文','109'
insert into test select '2006级期末考','20080303','王五','语文','100'
insert into test select '2006级期末考','20080101','张三','数学','101'
insert into test select '2006级期末考','20080202','李四','数学','85'
insert into test select '2006级期末考','20080303','王五','数学','58'
insert into test select '2006级期末考','20080101','张三','政治','56'
insert into test select '2006级期末考','20080202','李四','政治','56'
insert into test select '2006级期末考','20080303','王五','政治','50'
insert into test select '2006级期末考','20080101','张三','英语','102'
insert into test select '2006级期末考','20080202','李四','英语','110'
insert into test select '2006级期末考','20080303','王五','英语','93'
go
--测试
declare @sql varchar(8000)
set @sql='select A1,A2,A3'
select @sql=@sql+',sum(case when A4='''+A4+''' then A5 else 0 end)['+A4+']' from
(select distinct A4 from test)a
set @sql=@sql+' from test group by A1,A2,A3 order by A1,A2,A3'

exec(@sql)


--删除测试环境
drop table test
set nocount off
/*--
A1 A2 A3 数学 英语 语文 政治
-------------------- -------------------- -------------------- ---------------------- ---------------------- ---------------------- ----------------------
2006级期末考 20080101 张三 101 102 101 56
2006级期末考 20080202 李四 85 110 109 56
2006级期末考 20080303 王五 58 93 100 50

*/
yf520gn 2008-11-12
  • 打赏
  • 举报
回复
普通行列转换 
问题:假设有张学生成绩表(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
suton 2008-11-12
  • 打赏
  • 举报
回复
sql版去看看,那里很多这样的问题.

一般是组合case语句到一个varchar的变量.

然后 exec这个sql.
yangzong18 2008-11-12
  • 打赏
  • 举报
回复
非常感谢jinjazz 结贴
nanchangfantasy 2008-11-12
  • 打赏
  • 举报
回复
学习中,哈哈

2,499

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧