关于学生成绩的sql server 查询操作 经典实用实例

关于三个表: 学生信息表, 成绩表,课程表进行组合查询的操作 ,话不多说,先上表信息。
学生成绩表
关于学生成绩的sql server 查询操作 经典实用实例_第1张图片
学生信息表
关于学生成绩的sql server 查询操作 经典实用实例_第2张图片
课程信息表
课程信息表
方便大家操作,附上创建表格记录代码,直接摘取就好

CREATE TABLE Member  --学生表
(
  MID  char(10) primary key,  --学生号
  MName  CHAR(50) NOT NULL  --姓名
)
GO
CREATE TABLE F  --课程表
(
 FID   char(10) primary key,    --课程号
FName  CHAR(50) NOT NULL --课程名
)
GO
CREATE TABLE score  --学生成绩表
(
  SID int identity(1,1) primary key,  --成绩记录号
  FID char(10)  foreign key(FID) references F(FID) ,     --课程号
  MID char(10)  foreign key(MID) references Member(MID) ,     --学生号
  Score  int NOT NULL    --成绩
)
GO
--课程表中插入数据--
INSERT INTO F(FID,FName)VALUES('F001','语文')
INSERT INTO F(FID,FName)VALUES('F002','数学')
INSERT INTO F(FID,FName)VALUES('F003','英语')
INSERT INTO F(FID,FName)VALUES('F004','历史')
--学生表中插入数据--
INSERT INTO Member(MID,MName)VALUES('M001','张萨')
INSERT INTO Member(MID,MName)VALUES('M002','王强')
INSERT INTO Member(MID,MName)VALUES('M003','李三')
INSERT INTO Member(MID,MName)VALUES('M004','李四')
INSERT INTO Member(MID,MName)VALUES('M005','阳阳')
INSERT INTO Member(MID,MName)VALUES('M006','虎子')
INSERT INTO Member(MID,MName)VALUES('M007','夏雪')
INSERT INTO Member(MID,MName)VALUES('M008','璐璐')
INSERT INTO Member(MID,MName)VALUES('M009','珊珊')
INSERT INTO Member(MID,MName)VALUES('M010','香奈儿')
--成绩表中插入数据--
INSERT INTO Score(FID,MID,Score)VALUES('F001','M001',78)
INSERT INTO Score(FID,MID,Score)VALUES('F002','M001',67)
INSERT INTO Score(FID,MID,Score)VALUES('F003','M001',89)
INSERT INTO Score(FID,MID,Score)VALUES('F004','M001',76)
INSERT INTO Score(FID,MID,Score)VALUES('F001','M002',89)
INSERT INTO Score(FID,MID,Score)VALUES('F002','M002',67)
INSERT INTO Score(FID,MID,Score)VALUES('F003','M002',84)
INSERT INTO Score(FID,MID,Score)VALUES('F004','M002',96)
INSERT INTO Score(FID,MID,Score)VALUES('F001','M003',70)
INSERT INTO Score(FID,MID,Score)VALUES('F002','M003',87)
INSERT INTO Score(FID,MID,Score)VALUES('F003','M003',92)
INSERT INTO Score(FID,MID,Score)VALUES('F004','M003',56)
INSERT INTO Score(FID,MID,Score)VALUES('F001','M004',80)
INSERT INTO Score(FID,MID,Score)VALUES('F002','M004',78)
INSERT INTO Score(FID,MID,Score)VALUES('F003','M004',97)
INSERT INTO Score(FID,MID,Score)VALUES('F004','M004',66)
INSERT INTO Score(FID,MID,Score)VALUES('F001','M006',88)
INSERT INTO Score(FID,MID,Score)VALUES('F002','M006',55)
INSERT INTO Score(FID,MID,Score)VALUES('F003','M006',86)
INSERT INTO Score(FID,MID,Score)VALUES('F004','M006',79)
INSERT INTO Score(FID,MID,Score)VALUES('F002','M007',77)
INSERT INTO Score(FID,MID,Score)VALUES('F003','M008',65)
INSERT INTO Score(FID,MID,Score)VALUES('F004','M007',48)
INSERT INTO Score(FID,MID,Score)VALUES('F004','M009',75)
INSERT INTO Score(FID,MID,Score)VALUES('F002','M009',88)

**经常需要的一个查询操作是 查询出每个学生的各科成绩,并且将他们的平均分按照等级划分
90-100———— A
80-90————B
70-80————C
0-70————D
并且进行降序排列**,就像这样
关于学生成绩的sql server 查询操作 经典实用实例_第3张图片


分析

明显这是将三个表进行了连接,并取出来想要的字段显示,我们可以现将三个表连接一下看一下结果什么样的

select * from score ,Member,F where score.MID=Member.MID and score.FID=F.FID

结果如下图
关于学生成绩的sql server 查询操作 经典实用实例_第4张图片
可以分析出来 每一条记录的是每个学生的课程成绩
再简化一下,只取需要的三个字段

select MName,FName,Score from score ,Member,F where score.MID=Member.MID and score.FID=F.FID 

关于学生成绩的sql server 查询操作 经典实用实例_第5张图片
需要一个名字,四个科目名字和四个成绩要对应上,所以这里采用case这个关键字

select MName AS 学生姓名,
语文=sum(case FName WHEN '语文' then score  end),
英语=sum(case FName WHEN '英语' then score  end),
数学=sum(case FName WHEN '数学' then score  end),
历史=sum(case FName WHEN '历史' then score  end))
from score,Member,F where score.MID=Member.MID AND score.FID=F.FID
GROUP BY MName

这样就成功的完成了第一步, 将每个学生的考试成绩进行了对应,
对于case的解读:
当对MName进行聚合的时候,每次碰到FName 是语文的 就把该条记录的成绩 放到语文下面, 以此类推就把成绩按照对应的位置分开了。
关于学生成绩的sql server 查询操作 经典实用实例_第6张图片
接下来就是求平均分 并且对平均分进行评价划分了,
这里一想又要用到case了

select MName AS 学生姓名,
语文=sum(case FName WHEN '语文' then score  end),
英语=sum(case FName WHEN '英语' then score  end),
数学=sum(case FName WHEN '数学' then score  end),
历史=sum(case FName WHEN '历史' then score  end),
**case 
when AVG(score)>=90 then 'A'
when 80<AVG(score) AND AVG(score)<=90 then 'B'
when 70<AVG(score) and AVG(score)<=80 then 'C'
else 'D'
END  as  评价**
from score,Member,F where score.MID=Member.MID AND score.FID=F.FID
GROUP BY MName
ORDER BY AVG(score) desc

关于学生成绩的sql server 查询操作 经典实用实例_第7张图片
到这里可以发现一个问题 有的同学是有的考试没有参加,所以成绩为空,这样他的平均分就是两门课的平均成绩,这样对其他同学明显不公平的,所以需要四门课的平均成绩。我们可以去sum()/4 解决 ,或者只取参加了四门课程的学生的平均成绩评估
还有一点记录中出现的NULL 值真的很难看,也要处理掉。这里的话楼主用的是isnull()函数。

select b.MName AS 学生姓名,
语文=isnull(sum(case FName WHEN '语文' then score  end),'0'),
英语=isnull(sum(case FName WHEN '英语' then score  end),'0'),
数学=isnull(sum(case FName WHEN '数学' then score  end),'0'),
历史=isnull(sum(case FName WHEN '历史' then score  end),'0'),
总分= sum(score),
平均分=SUM(score)/4,
COUNT(b.MID) as 参加考试科目,
case 
when SUM(score)/4>=90 then 'A'
when 80<=SUM(score)/4 AND SUM(score)/4<90 then 'B'
when 70<=SUM(score)/4 and SUM(score)/4<80 then 'C'
else 'D'
END  as  评价
from score a LEFT  join Member b on a.MID=b.MID
left join F on F.FID=A.FID
group by b.MName
having COUNT(b.MID)>=4
order by 平均分  desc

关于学生成绩的sql server 查询操作 经典实用实例_第8张图片
这样结果就完美了!
如果不明白的地方,或者大家对我有批评指正的地方,欢迎大家在下方留言,感激不尽!
PS: 主体内容摘取自红黑联盟(http://www.2cto.com/database/201409/330246.html)

你可能感兴趣的:(sql-server)