问题:
1.统计本次考试的缺考情况 。
2.提取学员的成绩信息并保存结果,包括学员姓名、学号、笔试成绩、机试成绩、是否通过,比较笔试平均分和机试平均分,较低者进行循环提分,但提分后最高分不能超过97分。提分后,统计学员的成绩和通过情况 。
3.提分后统计学员的通过率情况。
分析:
使用子查询统计缺考情况:
应到人数:SELECT count(*) FROM stuInfo
实到人数:SELECT count(*) FROM stuMarks
提取学员的成绩信息并保存结果,包括学员姓名、学号、笔试成绩、机试成绩、是否通过
提取的成绩信息包含两表的数据,所以考虑两表连接,使用左连接(left join);
SELECT stuName…FROM stuInfo left Join stuMarks …
ON stuInfo.stuNo=stuMarks.stuNo
要求新加一列“是否通过(isPass)”,可采用CASE …END,如果笔试和机试都>60分,则通过。为了便于后续的通过率统计,通过则为1,没通过为0
SELECT … isPass=CASE
WHEN writtenExam>=60 and labExam>=60 THEN 1
ELSE 0
END
FROM …
要求保存提取(查询)的结果,可以使用我们曾学习过的SELECT …INTO newTable语句,生成新表并保存数据;生成新表前,需要检测是否已存在newTable表
IF EXISTS(SELECT * FROM sysobjects where name='newTable')
DROP TABLE newTable
SELECT …INTO newTable….
比较笔试平均分和机试平均分,较低者进行循环提分,但提分后最高分不能超过97分:
定义2个变量:分别存放笔试和机试平均分,然后使用AVG( )函数从表中获取数据并赋值;
使用IF语句判断笔试还是机试偏低,决定对笔试还是机试提分;
使用WHILE循环给每个学员加分,缺考的除外,当最高分超过97分时退出循环;
因为给每位学员的笔试或机试提分了,有的学员可能提分后刚好通过了,所以需要更新isPass(是否通过)列。
UPDATE newTable
SET isPass=CASE
WHEN writtenExam>=60 and labExam>=60 THEN 1
ELSE 0
END
提分后,统计学员的成绩和通过情况:
1)使用别名实现中文字段名,即SELECT 姓名=stuName,学号=stuNo…
2)如果某个学员的成绩为NULL(空),则替换为”缺考”,否则原样显示;
3)isPass列中的1替换为是,0替换为否;
SELECT 姓名=stuName,学号=stuNo,
笔试成绩=CASE
WHEN writtenExam IS NULL THEN '缺考'
ELSE convert(varchar(5),writtenExam)
END
,机试成绩=CASE
WHEN labExam IS NULL THEN '缺考'
ELSE convert(varchar(5),labExam)
END
,是否通过=CASE
WHEN isPass=1 THEN '是'
ELSE '否'
END
FROM newTable
提分后统计学员的通过率情况:
1)通过人数:因为通过用1表示,没通过用0表示,所以isPass列的累加和即是通过人数;
2)通过率:同理,isPass列的平均值*100即是通过率;
/*--本次考试的原始数据--*/
--SELECT * FROM stuInfo
--SELECT * FROM stuMarks
/*--------------统计考试缺考情况----------------------*/
SELECT 应到人数=(SELECT count(*) FROM stuInfo) , --应到人数为子查询表达式的别名
实到人数=(SELECT count(*) FROM stuMarks) ,
缺考人数=((SELECT count(*) FROM stuInfo)-(SELECT count(*) FROM stuMarks))
/*----统计考试通过情况,并将结果存放在新表newTable中---*/
IF EXISTS(SELECT * FROM sysobjects
WHERE name='newTable')
DROP TABLE newTable
SELECT stuName,stuInfo.stuNo,writtenExam ,labExam ,
isPass=CASE
WHEN writtenExam>=60 and labExam>=60 THEN 1
ELSE 0
END
INTO newTable FROM stuInfo
LEFT JOIN stuMarks
ON stuInfo.stuNo=stuMarks.stuNo
--SELECT * FROM newTable --查看统计结果,可用于调试
/*-酌情加分:比较笔试和机试平均分,决定加哪门---*/
DECLARE @avgWritten numeric(4,1)
DECLARE @avgLab numeric(4,1)
SELECT @avgWritten=AVG(writtenExam) FROM newTable
WHERE writtenExam IS NOT NULL
SELECT @avgLab=AVG(labExam)FROM newTable
WHERE labExam IS NOT NULL
IF @avgWritten<@avgLab
WHILE (1=1) --循环给笔试加分,最高分不能超过97分
BEGIN
UPDATE newTable SET writtenExam=writtenExam+1
IF (SELECT MAX(writtenExam) FROM newTable )>=97
BREAK
END
ELSE …略… --循环给机试加分,最高分不能超过97分
--因为提分,所以需要更新isPass(是否通过)列的数据
UPDATE newTable
SET isPass=CASE
WHEN writtenExam>=60 and labExam>=60 THEN 1
ELSE 0
END
--SELECT * FROM newTable --可用于调试
/*--------------显示考试最终通过情况----------------*/
SELECT 姓名=stuName,学号=stuNo
,笔试成绩=CASE
WHEN writtenExam IS NULL THEN '缺考'
ELSE convert(varchar(5),writtenExam)
END
,机试成绩=CASE
WHEN labExam IS NULL THEN '缺考'
ELSE convert(varchar(5),labExam)
END
,是否通过=CASE
WHEN isPass=1 THEN '是'
ELSE '否'
END
FROM newTable
/*--显示通过率及通过人数--*/
SELECT 总人数=count(*) ,通过人数=SUM(isPass),
通过率=(convert(varchar(5),AVG(isPass*100))+'%') FROM newTable