这个sql该怎么写,把记录内容作为字段?

bottlerun 2009-10-18 05:27:48
我有几张表
students 学生信息表
---------------
id 姓名
1 张三
2 李四

subjects 科目表
---------------
id 名称
1 数学
2 语文
3 英语

scores 考试成绩表
---------------------
student_id subject_id score
1 1 80
1 2 79
1 3 90
2 1 56
2 2 90
2 3 80


能不能写一条sql语句得出这样的结果,列是科目 和总分,行是学生姓名及得分情况
-----------------------------
姓名 数学 语文 英语 总分
张三 80 79 90 249
李四 56 90 80 226


我不想在程序里自己去实习,而希望sql直接能查出这种结果,方便进行排名什么的
...全文
219 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
DN_XIAOXIAO 2009-10-18
  • 打赏
  • 举报
回复
行转列。。
--小F-- 2009-10-18
  • 打赏
  • 举报
回复
----------------------------------------------------------------
-- Author :fredrickhu(小F,向高手学习)
-- Date :2009-10-18 17:53:48
-- Version:
-- Microsoft SQL Server 2005 - 9.00.4035.00 (Intel X86)
-- Nov 24 2008 13:01:59
-- Copyright (c) 1988-2005 Microsoft Corporation
-- Developer Edition on Windows NT 5.1 (Build 2600: Service Pack 3)
--
----------------------------------------------------------------
--> 测试数据:[students]
if object_id('[students]') is not null drop table [students]
go
create table [students]([id] int,[姓名] varchar(4))
insert [students]
select 1,'张三' union all
select 2,'李四'
--> 测试数据:[subjects]
if object_id('[subjects]') is not null drop table [subjects]
go
create table [subjects]([id] int,[名称] varchar(4))
insert [subjects]
select 1,'数学' union all
select 2,'语文' union all
select 3,'英语'
--> 测试数据:[scores]
if object_id('[scores]') is not null drop table [scores]
go
create table [scores]([student_id] int,[subject_id] int,[score] int)
insert [scores]
select 1,1,80 union all
select 1,2,79 union all
select 1,3,90 union all
select 2,1,56 union all
select 2,2,90 union all
select 2,3,80
--------------开始查询--------------------------
select a.[姓名] as 姓名 ,
max(case b.[名称] when '数学' then c.[score] else 0 end) 数学,
max(case b.[名称] when '语文' then c.[score] else 0 end) 语文,
max(case b.[名称] when '英语' then c.[score] else 0 end) 英语,
sum(c.score) as 总分
from
[students] a,[subjects] b,[scores] c
where
a.[id]=c.[student_id]
and
b.[id]=c.[subject_id]
group by
a.姓名

----------------结果----------------------------
/*姓名 数学 语文 英语 总分
---- ----------- ----------- ----------- -----------
李四 56 90 80 226
张三 80 79 90 249

(2 行受影响)
*/
  • 打赏
  • 举报
回复
---------------------------------
-- Author: HEROWANG(让你望见影子的墙)
-- Date : 2009-10-18 17:46:19
---------------------------------

IF OBJECT_ID('[students]') IS NOT NULL
DROP TABLE [students]
go
CREATE TABLE [students] (id INT,姓名 VARCHAR(4))
INSERT INTO [students]
SELECT 1,'张三' UNION ALL
SELECT 2,'李四'

select * from [students]
---------------------------------
-- Author: HEROWANG(让你望见影子的墙)
-- Date : 2009-10-18 17:46:38
---------------------------------

IF OBJECT_ID('[subjects]') IS NOT NULL
DROP TABLE [subjects]
go
CREATE TABLE [subjects] (id INT,名称 VARCHAR(4))
INSERT INTO [subjects]
SELECT 1,'数学' UNION ALL
SELECT 2,'语文' UNION ALL
SELECT 3,'英语'

select * from [subjects]
---------------------------------
-- Author: HEROWANG(让你望见影子的墙)
-- Date : 2009-10-18 17:47:00
---------------------------------

IF OBJECT_ID('[scores]') IS NOT NULL
DROP TABLE [scores]
go
CREATE TABLE [scores] (student_id INT,subject_id INT,score INT)
INSERT INTO [scores]
SELECT 1,1,80 UNION ALL
SELECT 1,2,79 UNION ALL
SELECT 1,3,90 UNION ALL
SELECT 2,1,56 UNION ALL
SELECT 2,2,90 UNION ALL
SELECT 2,3,80

select * from [scores]

select 姓名,名称,score from students a ,subjects b ,scores c
where a.id=c.student_id and b.id=c.subject_id

declare @sql varchar(8000)
set @sql=' '
select @sql=@sql+','+名称+'=max(case when 名称='''+名称+''' then score end)'
from subjects
print @sql


exec('select 姓名'+@sql+',总分=sum(score) from students a ,subjects b ,scores c where a.id=c.student_id and b.id=c.subject_id group by 姓名')

姓名 数学 语文 英语 总分
李四 56 90 80 226
张三 80 79 90 249
wangjianbo88 2009-10-18
  • 打赏
  • 举报
回复
细嚼慢咽
dawugui 2009-10-18
  • 打赏
  • 举报
回复
create table students(id int, 姓名 varchar(10)) 
insert into students values(1 , '张三')
insert into students values(2 , '李四')
create table subjects(id int, 名称 varchar(10))
insert into subjects values(1 , '数学')
insert into subjects values(2 , '语文')
insert into subjects values(3 , '英语')
create table scores(student_id int,subject_id int,score int)
insert into scores values(1 , 1 , 80 )
insert into scores values(1 , 2 , 79 )
insert into scores values(1 , 3 , 90 )
insert into scores values(2 , 1 , 56 )
insert into scores values(2 , 2 , 90 )
insert into scores values(2 , 3 , 80 )
go

--如果你科目固定为:数学 语文 英语,则用静态SQL。
select t1.姓名 ,
max(case t2.名称 when '数学' then t3.score else 0 end) [数学],
max(case t2.名称 when '语文' then t3.score else 0 end) [语文],
max(case t2.名称 when '英语' then t3.score else 0 end) [英语],
sum(t3.score) 总分
from students t1, subjects t2, scores t3
where t1.id = t3.student_id and t2.id = t3.subject_id
group by t1.姓名
/*
姓名 数学 语文 英语 总分
---------- ----------- ----------- ----------- -----------
李四 56 90 80 226
张三 80 79 90 249

(所影响的行数为 2 行)
*/

--如果你科目不固定为:数学 语文 英语,则用动态SQL。
declare @sql varchar(8000)
set @sql = 'select t1.姓名 '
select @sql = @sql + ' , max(case t2.名称 when ''' + 名称 + ''' then t3.score else 0 end) [' + 名称 + ']'
from (select distinct 名称 from subjects) as a
set @sql = @sql + ' , sum(t3.score) 总分 from students t1, subjects t2, scores t3 where t1.id = t3.student_id and t2.id = t3.subject_id group by t1.姓名'
exec(@sql)
/*
姓名 数学 英语 语文 总分
---------- ----------- ----------- ----------- -----------
李四 56 80 90 226
张三 80 90 79 249
*/

drop table students , subjects , scores
叶子 2009-10-18
  • 打赏
  • 举报
回复

/*
标题:普通行列转换(version 2.0)
作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
时间:-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 课程
set @sql = '[' + @sql + ']'
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

dawugui 2009-10-18
  • 打赏
  • 举报
回复

/*
标题:普通行列转换(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 课程
set @sql = '[' + @sql + ']'
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
叶子 2009-10-18
  • 打赏
  • 举报
回复
行列转换

34,838

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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