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

InnoDB使用redologs和undologs确保数据一致性和可靠性。1.redologs记录数据页修改,确保崩溃恢复和事务持久性。2.undologs记录数据原始值,支持事务回滚和MVCC。

EXPLAIN命令的关键指标包括type、key、rows和Extra。1)type反映查询的访问类型,值越高效率越高,如const优于ALL。2)key显示使用的索引,NULL表示无索引。3)rows预估扫描行数,影响查询性能。4)Extra提供额外信息,如Usingfilesort提示需要优化。

Usingtemporary在MySQL查询中表示需要创建临时表,常见于使用DISTINCT、GROUPBY或非索引列的ORDERBY。可以通过优化索引和重写查询避免其出现,提升查询性能。具体来说,Usingtemporary出现在EXPLAIN输出中时,意味着MySQL需要创建临时表来处理查询。这通常发生在以下情况:1)使用DISTINCT或GROUPBY时进行去重或分组;2)ORDERBY包含非索引列时进行排序;3)使用复杂的子查询或联接操作。优化方法包括:1)为ORDERBY和GROUPB

MySQL/InnoDB支持四种事务隔离级别:ReadUncommitted、ReadCommitted、RepeatableRead和Serializable。1.ReadUncommitted允许读取未提交数据,可能导致脏读。2.ReadCommitted避免脏读,但可能发生不可重复读。3.RepeatableRead是默认级别,避免脏读和不可重复读,但可能发生幻读。4.Serializable避免所有并发问题,但降低并发性。选择合适的隔离级别需平衡数据一致性和性能需求。

MySQL适合Web应用和内容管理系统,因其开源、高性能和易用性而受欢迎。1)与PostgreSQL相比,MySQL在简单查询和高并发读操作上表现更好。2)相较Oracle,MySQL因开源和低成本更受中小企业青睐。3)对比MicrosoftSQLServer,MySQL更适合跨平台应用。4)与MongoDB不同,MySQL更适用于结构化数据和事务处理。

MySQL索引基数对查询性能有显着影响:1.高基数索引能更有效地缩小数据范围,提高查询效率;2.低基数索引可能导致全表扫描,降低查询性能;3.在联合索引中,应将高基数列放在前面以优化查询。

MySQL学习路径包括基础知识、核心概念、使用示例和优化技巧。1)了解表、行、列、SQL查询等基础概念。2)学习MySQL的定义、工作原理和优势。3)掌握基本CRUD操作和高级用法,如索引和存储过程。4)熟悉常见错误调试和性能优化建议,如合理使用索引和优化查询。通过这些步骤,你将全面掌握MySQL的使用和优化。

MySQL在现实世界的应用包括基础数据库设计和复杂查询优化。1)基本用法:用于存储和管理用户数据,如插入、查询、更新和删除用户信息。2)高级用法:处理复杂业务逻辑,如电子商务平台的订单和库存管理。3)性能优化:通过合理使用索引、分区表和查询缓存来提升性能。


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

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

热门文章

热工具

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 英文版
推荐:为Win版本,支持代码提示!

SublimeText3 Linux新版
SublimeText3 Linux最新版