sql server多行数据合并显示

现有三个数据表,分别是学生表,课程表,成绩表。它们的结构与样例数据如下:
学生表:
xno         xname

1             小王
2              小黑

课程表:
kno         kname

1             语文
2             数学
成绩表
cno         ckno              cf

1                1                86.5
1               2                 98.86
2               1                 86.7
2               2                 86.9

 

create  table 学生表

(  
xno int ,
 xname varchar(20

)
go 



insert into dbo.学生表 
select 1,'小王'
union all 
select 2,'小黑' 


create table 课程表
(
kno int ,
kname varchar(20)

)
go

insert into 课程表
select 1,'语文'
union all
select 2,'数学'





create table 成绩表
(
cno int,
ckno int,
cf float
)




alter table 成绩表
alter column cf 

insert into 成绩表
select 1,1,86.5


insert into 成绩表
select 1,2,98.86

union all

select 2,1,86.7
union all
select 2,2,86.9




select * from 学生表
select * from 课程表
select * from 成绩表


现要求在一行中输出每个学生的所有课程的成绩单,显示样例格式如下:
姓名        语文        数学      

小王        60            70          

小黑        80            65          

 

当大家看到这样的题目时会优先考虑到的是怎样的一条SQL语句呢?嵌套Select?对,在将行转换为列时,也许这种方法是最优先考虑到

 

SELECT B.xname,
(SELECT cf FROM 成绩表 INNER JOIN 课程表 ON 成绩表.ckno=课程表.kno WHERE 成绩表.cno=B.xno AND 课程表.kname='语文' ) AS 语文,
(SELECT cf FROM 成绩表 INNER JOIN 课程表 ON 成绩表.ckno=课程表.kno WHERE 成绩表.cno=B.xno AND 课程表.kname='数学' ) AS 数学
FROM 学生表 B

 

这样我们的目的是达到了,但后来我又想了一下,因为我们要的数据其实都在成绩表里,只不过现有的是用行来存放,那我们怎么将它转换为列显示呢?嗯,这也许就要搬出聚合函数加Case条件来处理了!最终的SQL语句如下:

SELECT xname,
MAX(CASE kname WHEN '语文' THEN cf ELSE 0 ENDAS 语文,
MAX(CASE kname WHEN '数学' THEN cf ELSE 0 ENDAS 数学
FROM (SELECT B.xname,C.kname,D.cf FROM 成绩表 D 
INNER JOIN 学生表 B ON B.xno=D.cno 
INNER JOIN 课程表 C ON C.kno=D.ckno) AS ZH GROUP BY xname


 

运行后,也是可以得到正确的数据,下面给出测试代码,大家可以直接在SQL查询分析器里运行

方法一:

SELECT B.xname,
(SELECT cf FROM 成绩表 INNER JOIN 课程表 ON 成绩表.ckno=课程表.kno WHERE 成绩表.cno=B.xno AND 课程表.kname='语文' ) AS 语文,
(SELECT cf FROM 成绩表 INNER JOIN 课程表 ON 成绩表.ckno=课程表.kno WHERE 成绩表.cno=B.xno AND 课程表.kname='数学' ) AS 数学
FROM 学生表 B

 

方法二:

SELECT xname,
MAX(CASE kname WHEN '语文' THEN cf ELSE 0 ENDAS 语文,
MAX(CASE kname WHEN '数学' THEN cf ELSE 0 ENDAS 数学
FROM (SELECT B.xname,C.kname,D.cf FROM 成绩表 D 
INNER JOIN 学生表 B ON B.xno=D.cno 
INNER JOIN 课程表 C ON C.kno=D.ckno) AS ZH GROUP BY xname


DROP TABLE 学生表
DROP TABLE 课程表
DROP TABLE 成绩表

 

posted @ 2011-11-28 16:38  qingsong_do  阅读(2554)  评论(0编辑  收藏  举报