• 数据查询(3)复杂查询


     

    什么是子查询 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

    问题:

    编写T-SQL语句,查看年龄比张三大的学员,要求显示这些学员的信息

    分析:

    第一步:求出张三的年龄;

    第二步:利用WHERE语句,筛选年龄比张三大的学员;

     

    实现方法一:采用T-SQL变量实现

    DECLARE @age INT  --定义变量,存放张三的年龄

    SELECT @age=stuAge FROM stuInfo

         WHERE stuName=‘张三      --求出张三的年龄

    --筛选比张三年龄大的学员

    SELECT * FROM stuInfo WHERE stuAge>@age

     GO

    有没有更简洁的语句呢?
    有,我们可以合并上述两步

     

    因为:

    1.除了“>”号外,还可以使用其他运算符号,习惯上,外面的查询称为父查询,括号中嵌入的查询称为子查询。

    2.SQL Server执行时,先执行子查询部分,求出子查询部分的值,然后再执行整个父查询。它的执行效率比采用SQL变量实现的方案一要高,所以推荐采用子查询。

    3.子查询作为WHERE条件的一部分,还可以和UPDATEINSERTDELETE一起使用,语法类似于SELECT语句。

     

    实现方法二:采用子查询实现

    SELECT * FROM stuInfo

    WHERE stuAge>( SELECT stuAge FROM 

                          stuInfo where stuName='张三')

    GO

     

    使用子查询替换表连接

    问题:查询笔试刚好通过(60分)的学员。

    我们可以根据学员信息表和成绩表,查询笔试刚好通过考试的学员。

    那么就有两种实现方案:

    1.因为涉及到两张表(学员信息表和成绩表,前面我们已经建立好了),所以可以采用曾学过的连接查询。

    2. 使用子查询。

     

    实现方法一:采用表连接

    SELECT stuName FROM stuInfo

        INNER JOIN   stuMarks

           ON  stuInfo.stuNo=stuMarks.stuNo

               WHERE writtenExam=60

    GO

    实现方法二:采用子查询

    SELECT stuName FROM stuInfo

         WHERE stuNo=(SELECT stuNo FROM 

                    stuMarks WHERE writtenExam=60)

    GO

    注意:

    1.一般来说,表连接都可以用子查询替换,但反过来说就不一定。有的子查询却不能用表连接替换。

    2.子查询比较灵活、方便、形式多样,常作为增、删、改、查的筛选条件,适合于操纵一个表的数据。

    3. 表连接更适合于查看多表的数据,一般用于SELECT查询语句。

     

    问题:查询笔试刚好通过的学员名单。

    提问:

        如果笔试成绩中有多个人刚好通过,即都为60分(例如我们再插入一条60分的数据)。使用我们刚才的子查询语句,会出现什么问题呢?(注意等号部分。)

    我们演示一下就会发现出现了编译错误。SQL Server要求:“>”等比较运算符号后的子查询,返回的值不能多于一个,即记录条数不能超过1条。那么如何解决呢?我们可以使用IN子查询。

     

    IN子查询

    SELECT stuName FROM stuInfo

       WHERE stuNo IN

         (SELECT stuNo FROM  stuMarks

                 WHERE writtenExam=60)

    GO

    1.  IN后面的子查询可以返回多条记录

    2.  常用IN替换等于(=)的比较子查询

     

    问题:查询参加考试的学员名单

    分析:

    判断一个学员是否参加考试其实很简单,只需要查看该学员对应的学号是否在考试成绩表stuMarks中出现即可

    /*--采用IN子查询参加考试的学员名单--*/

    SELECT stuName FROM stuInfo

      WHERE stuNo IN (SELECT stuNo FROM stuMarks)

    GO

     

    NOT IN子查询

    问题:查询未参加考试的学员名单

    分析:加上否定的NOT 即可

     

    EXISTS子查询

    EXISTS语句我们并不陌生,我们在学习建库和建表语句时曾提前用过,它是一个存在检测的子查询语句

    IF EXISTSSELECT * FROM 

           sysDatabases WHERE name=’stuDB’

        DROP DATABASE stuDB

    CREATE DATABASE stuDB

    …….—建库代码略

     

    EXISTS子查询的语法:

    IF EXISTS (子查询)

    语句

    1.   如果子查询的结果非空,即记录条数1条以上,则EXISTS (子查询)将返回真(true),否则返回假(false)

    2.   EXISTS也可以作为WHERE 语句的子查询,但一般都能用IN子查询替换

     

    问题:

    检查本次考试,本班如果有人笔试成绩达到80分以上,则每人提2分;否则,每人允许提5

     

    分析:

    是否有人笔试成绩达到80分以上,可以采用EXISTS检测

    /*--采用EXISTS子查询,进行酌情加分--*/

    IF EXISTS (SELECT * FROM stuMarks WHERE writtenExam>80)

      BEGIN

        print '本班有人笔试成绩高于80分,每人加2分,加分后的成绩为:'

        UPDATE stuMarks SET writtenExam=writtenExam+2

        SELECT * FROM stumarks

      END

    ELSE

      BEGIN

        print '本班无人笔试成绩高于80分,每人可以加5分,加分后的成绩:'

        UPDATE stuMarks SET writtenExam=writtenExam+5

        SELECT * FROM stumarks

      END

    GO

    问题:

    检查本次考试,本班如果没有一人通过考试(笔试和机试成绩都>60分),则试题偏难,每人加3分,否则,每人只加1

     

    分析:

    没有一人通过考试,即不存在笔试和机试成绩都>60,可以采用NOT EXISTS检测

    IF NOT EXISTS (SELECT * FROM stuMarks WHERE

                                    writtenExam>60 AND labExam>60)

      BEGIN

        print '本班无人通过考试,试题偏难,每人加3分,加分后的成绩为:'

        UPDATE stuMarks

             SET writtenExam=writtenExam+3,labExam=labExam+3

        SELECT * FROM stuMarks

      END

    ELSE

      BEGIN

        print '本班考试成绩一般,每人只加1分,加分后的成绩为:'

        UPDATE stuMarks

             SET writtenExam=writtenExam+1,labExam=labExam+1

        SELECT * FROM stuMarks

      END

    GO

  • 相关阅读:
    Zookeeper 笔记
    个人学习笔记
    VS Window窗体 (C#)程序 连接sql server 数据库
    每周总结 11.9~11.15
    需求分析 第七稿 功能实现进度09
    数据简单清洗和图标联动展示
    IDEA创建文件自动添加作者名及时间
    springcloudalibaba中文文档
    ContractHolder.parseAndValidateMetadata(Ljava/lang/Class;)Ljava/util/List;
    Sentinel fallback失效
  • 原文地址:https://www.cnblogs.com/CharmingDang/p/9663731.html
Copyright © 2020-2023  润新知