热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

第四章高级查询

4.1简单子查询究竟什么是子查询?子查询有什么用?带着这样的疑问,我们不妨先来解决本章第一个问题。学员信息表(stuInfo)和学员成绩表(stuMarks)的数据。stuNamestuNostuSexstuAgestuSeatstuAddress张秋丽s25301男181北京海淀李思文s25303女222河

4.1 简单子查询 究竟什么是子查询?子查询有什么用?带着这样的疑问,我们不妨先来解决本章第一个问题。 学员信息表(stuInfo)和学员成绩表(stuMarks)的数据。 stuNamestuNostuSexstuAgestuSeatstuAddress 张秋丽s25301男181北京海淀 李思文s25303女222河

4.1 简单子查询

  究竟什么是子查询?子查询有什么用?带着这样的疑问,我们不妨先来解决本章第一个问题。

  学员信息表(stuInfo)和学员成绩表(stuMarks)的数据。

stuName stuNo stuSex stuAge stuSeat stuAddress

张秋丽 s25301 男 18 1 北京海淀

李思文 s25303 女 22 2 河南洛阳

李文才 s25302 男 85 3 地址不详

欧阳俊雄 s25304 男 28 4 新疆

梅超风 s25318 女 23 5 地址不详

ExamNo stuNo writtenExam labExam

s271811 s25303 90 58

s271813 s25302 60 90

s271816 s25301 87 82

  问题:查看年龄比“李思文”大的学员,要求显示这些学员的信息。

  实现方法一:采用T-SQL变量实现,SQL语句如示例1所示。

  示例1

  Declare @age int   ---定义变量,用于存放“李思文”的年龄

  Select @age = stuAge From stuInfo where stuName = '李思文'   ---求出“李思文”的年龄

  Select * from stuInfo where stuAge > @age   ---筛选比“李思文”年龄大的学员

  GO

  实现方法二:采用子查询实现,SQL语句如示例2所示。

  我们可以合并上述两步。

  将语句  Select * from stuInfo where stuAge > @age

  替换为如示例2所示的语句

  示例2

  Select * from stuInfo Where stuAge > ( select stuAge from stuInfo where stuName > '李思文')

  Go

  你一定明白了,上述查询中的“( select stuAge from stuInfo where stuName > '李思文')”部分,就是子查询,因为它嵌入到查询中作为Where条件的一部分。

  所以它在Where语句中的一般用法如下。

  Select ··· from 表1 Where 字段1 > (子查询)

  除了“>” 号外,还可以使用其他运算符号,习惯上,外面的查询称为父查询,括号中嵌入的查询称为子查询。SQL Server 执行时,先执行子查询部分,求出子查询部分的值,然后再执行整个父查询。它的执行效率比采用SQL变量实现的方案要高,所以推荐采用子查询。因为子查询作为Where条件的一部分,所以还可以和Update、Insert、Delete一起使用,语法类似于Select语句。

  注: 将子查询和比较运算符联合使用,必须保证子查询返回的值不能多于一个。

  上述子查询将多个结果集合并在一起,除此之外,还可以将多表间的数据组合在一起,从而替换连接(Join)查询。

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

  实现方法一: 采用表连接。

  示例3

  Select stuName from stuInfo inner join stuMarks

    On stuInfo.stuNo = stuMarks.stuNo where writtenExam = 60

  GO

  除了采用表连接以外,还可以采用子查询替换上述连接。

  实现方法二:采用子查询

  示例4

  Select stuName From stuInfo where stuNo = (select stuNo from stuMarks where writtenExam = 60)  GO

  注:一般来说,表连接都可以用子查询替换,但反过来说却不一定,有的子查询不能用表连接来替换。子查询比较灵活、方便,形式多样,适合于作为查询的筛选条件。而表连接更适合于查看多表的数据。

4.2 IN 和 Not In 子查询

  使用“=”、“>” 等比较运算符时,要求子查询只能返回一条或空的记录。在SQL Server中,香港虚拟主机,当子查询跟随在 = 、!= 、<、<=、>、>=之后,不允许子查询返回多条记录。例如上例查询笔试刚好及格的学员信息,成绩表中刚好只有一条记录满足条件:李文才(s25302)的笔试成绩刚好60分。如果有多条记录满足条件,既有多个学员的笔试成绩为60分,采用上述子查询将出现编译错误。

  示例5

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

  Select stuName from stuInfo where stuNo in (select stuNo from stuMarks) GO

  同理,如果希望查询未参加考试的学员名单呢?您一定想到了,加上否定的Not 即可。

  /*-- 采用Not in 子查询,查看未参加考试的学员名单 --*/

  Select stuName from stuInfo where stuNo Not in (select stuNo from stuMarks) GO

4.3 Exists 和 Not Exists 子查询

  Exists 语句我们并不陌生,在学习创建库和创建表的语句时曾提前用过,它是一个存在检测的子查询语句。例如,如果存在数据库stuDB,则先删除它,然后重新创建。

  IF Exists (select * from sysDatabases where name = 'stuDB')

    Drop DataBase stuDB

  Create DataBase stuDB

  ··· 创建的库代码略

  从理论上讲,Exists 也可以作为Where语句的子查询,但一般用于IF语句的存在检测。其基本语法如下:

  IF Exists(子查询)

    语句

  如果子查询的结果非空,则Exists(子查询)将返回真(true),否则返回假(false)。

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

  示例8

  /*-- 采用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

  Exists 和 in 一样,同样允许添加Not取反,表示不存在。

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

  示例9

  /*--- 采用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

4.4 T-SQL 语句的综合应用

  假定目前本次考试学员信息表(stuInfo)和学员成绩表(stuMarks)的原始数据如下:

stuName stuNo stuSex stuAge stuSeat stuAddress

张秋丽 s25301 男 18 1 北京海淀

李思文 s25303 女 22 2 河南洛阳

李文才 s25302 男 85 3 地址不详

欧阳俊雄 s25304 男 28 4 新疆

梅超风 s25318 女 23 5 地址不详

ExamNo stuNo writtenExam LabExam

s271811 s25303 93 59

s271813 s25302 63 91

s271816 s25301 90 83

s271817 s25318 63 53

  问题:

  (1)统计本次考试的缺考情况,结果如图第一个记录集所示。

应到人数 实到人数 缺考人数

5 4 1

姓名 学号 笔试成绩 机试成绩 是否通过

张秋丽 s25301 90 89 是

李思文 s25303 93 65 是

李文才 s25302 63 97 是

欧阳俊雄 s25304 缺考 缺考 否

梅超风 s25318 63 59 否

总人数 通过人数 通过率

5 3 60%

  (2)提取学员的成绩信息并保存结果,香港服务器,包括学员姓名、学号、笔试成绩、机试成绩、是否通过。

  (3)比较笔试平均分和机试平均分,较低者进行循环提分,但提分后最高分不能超过97分。

  (4)提分后,香港空间,统计学员的成绩和通过情况,如上图第二个记录集所示。

  (5)提分后统计学员的通过率情况,如上图第三个记录集所示。

  示例10

  /*--- 本次考试的原始数据 ---*/

  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

    Info newTable from stuInfo Left Join stuMarks

      On stuInfo.stuNo = stuMarks.stuNo

  /*--- 酌情加分:比较笔试和机试平均分,哪科偏低,就给哪科提分 ---*/

  Declare @avgWritten numeric (4,1), @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

    While(1=1) ---循环给机试加分,最高分不能超过97分

      Begin

        Update newTable set labExam = labExam + 1

        If(select Max(labExam) from newTable) >= 97

          Break

      End

  --- 因为提分,所以需要更新isPass(是否通过)列的数据

  Update newTable

    Set isPass = Case

      When writtenExam >= 60 and labExam >= 60 Then 1

      Else 0

    End

  /*--- 显示考试最终通过情况 ---*/

  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

  Go

推荐阅读
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 基于PgpoolII的PostgreSQL集群安装与配置教程
    本文介绍了基于PgpoolII的PostgreSQL集群的安装与配置教程。Pgpool-II是一个位于PostgreSQL服务器和PostgreSQL数据库客户端之间的中间件,提供了连接池、复制、负载均衡、缓存、看门狗、限制链接等功能,可以用于搭建高可用的PostgreSQL集群。文章详细介绍了通过yum安装Pgpool-II的步骤,并提供了相关的官方参考地址。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 生成对抗式网络GAN及其衍生CGAN、DCGAN、WGAN、LSGAN、BEGAN介绍
    一、GAN原理介绍学习GAN的第一篇论文当然由是IanGoodfellow于2014年发表的GenerativeAdversarialNetworks(论文下载链接arxiv:[h ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文介绍了Python版Protobuf的安装和使用方法,包括版本选择、编译配置、示例代码等内容。通过学习本教程,您将了解如何在Python中使用Protobuf进行数据序列化和反序列化操作,以及相关的注意事项和技巧。 ... [详细]
author-avatar
铥铥宇900
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有