第四章 高级查询
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
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

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

12306订票app下载最新版是一款大家非常满意的出行购票软件,想去哪里就去那里非常方便,软件内提供的票源非常多,只需要通过实名认证就能在线购票,所有用户的出行车票机票都可以轻松买到,享受不同的优惠折扣。还能提前开启预约抢票,预约酒店、专车接送都是可以的,有了它想去哪里就去那里一键购票,出行更加简单方便,让大家的出行体验更舒服,现在小编在线详细为12306用户们带来查看历史购票记录的方法。 1.打开铁路12306,点击右下角我的,点击我的订单 2.在订单页面点击已支付。 3.在已支付页

学信网如何查询自己的学历?在学信网中是可以查询到自己的学历,很多用户都不知道如何在学信网中查询到自己的学历,接下来就是小编为用户带来的学信网查询自己学历方法图文教程,感兴趣的用户快来一起看看吧!学信网使用教程学信网如何查询自己的学历一、学信网入口:https://www.chsi.com.cn/二、网站查询:第一步:点击上方学信网地址,进入首页点击【学历查询】;第二步:在最新的网页中点击如下图箭头所示的【查询】;第三步:之后在新页面点击【的登陆学信档案】;第四步:在登陆页面输入信息点击【登陆】;

MySQL与PL/SQL是两种不同的数据库管理系统,分别代表了关系型数据库和过程化语言的特点。本文将比较MySQL和PL/SQL的异同点,并附带具体的代码示例进行说明。MySQL是一种流行的关系型数据库管理系统,采用结构化查询语言(SQL)来管理和操作数据库。而PL/SQL是Oracle数据库特有的过程化语言,用于编写存储过程、触发器和函数等数据库对象。相同

使用苹果手机想要查询激活日期,最好的方法是通过手机中的序列号来查询,也可以通过访问苹果的官网来进行查询,通过连接电脑查询,下载第三方软件查询。苹果手机怎么查询激活日期答:序列号查询,苹果官网查询,电脑查询,第三方软件查询1、用户最好的方式就是知道自己手机的序列号,打开设置通用关于本机就可以看到序列号。2、使用序列号不仅可以知道自己手机的激活日期,还可以查看手机版本,手机产地,手机出厂日期等。3、用户访问苹果的官网找到技术支持,找到页面底部的服务和维修栏目,里面查看iPhone的激活信息。4、用户

标题:如何使用Oracle查询表是否被锁?在Oracle数据库中,表锁是指当一个事务正在对表执行写操作时,其他事务想要对该表执行写操作或者对表进行结构改变(如增加列、删除行等)时会被阻塞。在实际开发过程中,我们经常需要查询表是否被锁,以便更好地排查和处理相关问题。本文将介绍如何使用Oracle语句查询表是否被锁,并给出具体的代码示例。要查询表是否被锁,我们

论坛是互联网上非常常见的网站形式之一,它为用户提供了一个分享信息、交流讨论的平台。而Discuz是一款常用的论坛程序,相信很多站长都已经非常熟悉了。在进行Discuz论坛的开发和管理过程中,经常需要查询数据库中的数据来进行分析或处理。在这篇文章中,我们将分享一些查询Discuz数据库位置的技巧,并提供具体的代码示例。首先,我们需要了解Discuz的数据库结构

查询BitTorrent币(BTT)最新价格BTT是TRON区块链上的加密货币,用于奖励BitTorrent网络用户分享和下载文件。查找BTT最新价格的方法如下:选择一个可靠的价格查询网站或应用程序。一些常用的价格查询网站包括:CoinMarketCap:https://coinmarketcap.com/Coindesk:https://www.coindesk.com/币安:https://www.binance.com/在网站或应用程序中搜索BTT。查看BTT的最新价格。注意:加密货币价格

如何查询通神币最新价格?通神币是一种数字货币,可用于购买游戏内物品、服务和资产。它是去中心化的,意味着它不受政府或金融机构的控制。通神币的交易在区块链上进行,这是一个分布式账本,记录了所有通神币交易的信息。要查询通神币的最新价格,您可以使用以下步骤:选择一个可靠的价格查询网站或应用程序。一些常用的价格查询网站包括:CoinMarketCap:https://coinmarketcap.com/Coindesk:https://www.coindesk.com/币安:https://www.bin
