T-SQL综合应用(重)

 
问题:
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
    SELECTINTO 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

 

posted @ 2014-11-13 09:18  博斯芮网络科技  阅读(474)  评论(0编辑  收藏  举报