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
    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
时间: 2024-12-09 08:05:59

T-SQL综合应用(重)的相关文章

关于T-SQL重编译那点事,WITH RECOMPILE和OPTION(RECOMPILE)区别仅仅是存储过程级重编译和SQL语句级重编译吗

本文出处:http://www.cnblogs.com/wy123/p/6262800.html   在考虑重编译T-SQL(或者存储过程)的时候,有两种方式可以实现强制重编译(前提是忽略导致重编译的其他因素的情况下,比如重建索引,更新统计信息等等), 一是基于WITH RECOMPILE的存储过程级别重编译,另外一种是基于OPTION(RECOMPILE)的语句级重编译. 之前了解的比较浅,仅仅认为是前者就是编译整个存储过程中的所有的语句,后者是重编译存储过程中的某一个语句,也没有追究到底是不

Oracle实践--PL/SQL综合之分页存储过程

当我们查看JDK API的时候,总会发现一些类说明写着,线程安全或者线程不安全,比如说StringBuilder中,有这么一句,"将StringBuilder 的实例用于多个线程是不安全的.如果需要这样的同步,则建议使用StringBuffer. ",那么下面手动创建一个线程不安全的类,然后在多线程中使用这个类,看看有什么效果. Count.java: [java] view plaincopy public class Count { private int num; public 

WITH RECOMPILE和OPTION(RECOMPILE)区别仅仅是存储过程级重编译和SQL语句级重编译

在考虑重编译T-SQL(或者存储过程)的时候,有两种方式可以实现强制重编译(前提是忽略导致重编译的其他因素的情况下,比如重建索引,更新统计信息等等), 一是基于WITH RECOMPILE的存储过程级别重编译,另外一种是基于OPTION(RECOMPILE)的语句级重编译. 之前了解的比较浅,仅仅认为是前者就是编译整个存储过程中的所有的语句,后者是重编译存储过程中的某一个语句,也没有追究到底是不是仅仅只有这么一点区别. 事实上在某些特定情况下,两者的区别并非仅仅是存储过程级重编译和语句级重编译的

SQL Server 2008 重起失败,删除PendingFileRenameOperations后仍无法重起问题的解决办法

最近在装SQLServer 2008,遇到了很多王有共同的问题---"sql server2008安装时提示重启计算机失败" 网上的解决办法很多,如 http://jingyan.baidu.com/article/a24b33cd52a0b919fe002bae.html,就给了很好的解决方案. 我根据上面链接给出的办法操作后,仍然提示"重起失败". 解决办法: 1  .照做"http://jingyan.baidu.com/article/a24b33

Hive SQL综合案例

一 Hive SQL练习之影评案例 案例说明 现有如此三份数据:1.users.dat 数据格式为: 2::M::56::16::70072, 共有6040条数据对应字段为:UserID BigInt, Gender String, Age Int, Occupation String, Zipcode String对应字段中文解释:用户id,性别,年龄,职业,邮政编码 2.movies.dat 数据格式为: 2::Jumanji (1995)::Adventure|Children's|Fan

mysql的sql筛选排重最大值并修改其属性

修改属性 mysql -h192.168.1.51 -uroot -e "use codex_game_s1051_h; update user_info set isActive=0 where 1=1" mysql -h192.168.1.51 -uroot -e "use codex_game_s1051_h; update user_info set isActive=1 where userId in (select r.userId from role r joi

常用的sql server规范

常见的字段类型选择 1.字符类型建议采用varchar/nvarchar数据类型 2.金额货币建议采用money数据类型 3.科学计数建议采用numeric数据类型 4.自增长标识建议采用bigint数据类型   (数据量一大,用int类型就装不下,那以后改造就麻烦了) 5.时间类型建议采用为datetime数据类型 6.禁止使用text.ntext.image老的数据类型 7.禁止使用xml数据类型.varchar(max).nvarchar(max) 约束与索引 每张表必须有主键 •每张表必

常用 SQL Server 规范集锦

常见的字段类型选择 1.字符类型建议采用varchar/nvarchar数据类型 2.金额货币建议采用money数据类型 3.科学计数建议采用numeric数据类型 4.自增长标识建议采用bigint数据类型   (数据量一大,用int类型就装不下,那以后改造就麻烦了) 5.时间类型建议采用为datetime数据类型 6.禁止使用text.ntext.image老的数据类型 7.禁止使用xml数据类型.varchar(max).nvarchar(max) 约束与索引 每张表必须有主键 每张表必须

SQL 触发器-如何查看当前数据库中有哪些触发器

在查询分析器中运行: use 数据库名goselect * from sysobjects where xtype='TR' sysobjects 保存着数据库的对象,其中 xtype 为 TR 的记录即为触发器对象.在 name 一列,我们可以看到触发器名称. SQL 触发器-创建一个简单的触发器 SQL 触发器-重命名触发器 SQL 触发器-删除触发器 SQL 触发器-触发器更多语法 SQL 触发器-如何查看某个触发器的内容 SQL 触发器-多个触发器 SQL 触发器-递归.嵌套触发器 SQ

linux 批量重命名文件

1. 分隔 >>split -l 5 data_out.sql test 2.重命名 >>for j in test*; do mv -v -- "$j" "$j.sql";done To export If it's an entire DB, then: $ mysqldump -u [uname] -p[pass] db_name > db_backup.sql If it's all DBs, then: $ mysqldump