Oracle数据库的嵌套查询
备注:此博客为转载,方便自己学习 Oracle的嵌套查询,原作者地址请点击此处
在前面2个章节,我们比较详细的介绍了一些SQL语句的基本用法,但是在我们实际的项目开发中,其实很多时候这些基本的用法远远不能满足我们项目的需求,这个时候就需要我们的嵌套查询。
在SQL语句中,一个select-from-where语句称为一耳光查询快。将一个查询快嵌套在另外一个的where子句或having 短语的条件的查询称为嵌套查询(Nested Query)。
比如,先举一个简单的例子:
select Sname --------------外查询语句块-------
from Student
where Sno in --------------外查询语句块------- ( --------------内查询语句块------- select SnoFrom Scwhere Cno=2--------------内查询语句块------- );
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
查询语句块分为外查询语句或叫父查询以及内查询或子查询。
NOTE:SQL语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询。需要特别指出的是,子查询的select语句中不能使用order by字句,order by 只能对最终查询结果排序。
一。带有in谓词的子查询
在嵌套查询中,子查询往往是一个集合,所以谓词in是嵌套查询中最经常使用的谓词。
【例1】查询与“XiaoHong”在同一个系的学生
OK,我们一步一步的来分解这个查询步骤:
①确定“XiaoHong”所在的系
select sdept
from student
where sname='XiaoHong'
- 1
- 2
- 3
得到的结果是:CS。
②查找所有在CS系学习的所有学生
select sno,sname,sdept
from student
where sdept='CS';
- 1
- 2
- 3
ok,得到如下结果:
③合并操作。
现在我们只需要把上面的操作合并在一起就好了!
select sno,sname,sdept
from student
where sdept in
(select sdeptfrom student where sname='XiaoHong'
);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
得到的结果也是一样。
本例中,因为子查询的查询条件不依赖于父查询,所以称为不相关查询。
当然本例中也还可以有其他解法:自连接方法如下:
select s1.sno,s1.sname,s1.sdept
from student s1,student s2
where s1.sdept=s2.sdept and s2.sname='XiaoHong';
- 1
- 2
- 3
可见,一个查询有很多种方法,当然不同的方法执行的效率可能会有很大的不同。
【例2】查询选修了课程名为”Math“的学生学号和姓名
看似这一句很短,其实这里有2个子查询。我们需要先弄清楚里面的关系,然后在来进行解答
思路如下:
1).课程名在course表中才有,所以我们从course表中选出课程名为Math的课程号(Cno)
2).选出课程号之后,在在SC表中,找到课程号所对应的学生号
3).在student表中找出对应的学号和学生名字。
select sno,sname --第三步,最后从student表中取出数据出来。
from student
where sno in
(select sno --第二步。。找出SC关系表中的选修了2号课程的学生学号 from sc where cno in(select cno -- 第一步。。找出course表中的课程名为math的课程号。结果为2.from course where cname='Math')
);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
结果如下:
代替方法:
select student.sno,sname from
student,sc,course
where course.cname='Math'
and course.cno=sc.cno and sc.sno=student.sno;
- 1
- 2
- 3
- 4
结果也是一样滴。
二。带有比较运算符的子查询
带有比较运算符的子查询是指父查询之间用比较运算符进行连接。当用户能确切知道内存查询返回的是单值时,可以用>,<,>=,<=,!=,<>等等比较运算符。
【例3】和例1 是一样的:查询与“XiaoHong”在同一个系的学生
因为一个学生只可能在一个系学习,也就是说内查询的结果是一个值,因此可以用“=”代替“in”
如下:
select sno,sname,sdept
from student
where sdept =
(select sdeptfrom student where sname='XiaoHong'
);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这样 也能得到和例1的结果。
需要注意的是,子查询一定要跟在比较符之后,下面写法是错误的:
----------------错误写法---------------------
select sno,sname,sdept
from student
where
(select sdeptfrom student where sname='XiaoHong') =sdept;
----------------错误写法---------------------
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
【例4】找出每个学生超过他选修课课程平均成绩的课程号
这个怎么理解呢?我们先把结果写出来,然后再来剖析它。
select sno,cno
from sc x
where grade>=
(select avg(grade) from sc y where y.sno=x.sno);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
x是Sc表的别名,y也是一样。内存查询是求一个学生所有选修课程平均成绩,至于是哪个学生的平均成绩要看s.sno的值。,而该值是和父查询有关的,所以这类查询叫做相关子查询。
执行过程可能如下:
①从外层查询中取出SC表中的一行(也就是元组 x),将x的值sno
select avg(Grade)
from sc y
where y.sno=1;
- 1
- 2
- 3
得到结果是98.5
②执行内查询得到的结果是:98.5,所以得到外查询是:
select sno,cno
from sc x
where Grade>=98.5;
- 1
- 2
- 3
得到结果如下:
然后,外层查询取出下一个元组重复做上面的动作。。。
得到的结果是:
三。带有any(some)或all谓词的子查询
子查询返回单值可以用比较算术法,但是返回多值时要用any(有些系统用some)或者all谓词修饰符。而是用any或all谓词时则必须同时是用比较运算符。
any 大于子查询结果中的某个值
select sname,sage
from student
where sage < any
(select sage from student where sdept='CS'
) and sdept <> 'CS'; -- 注意这是父查询的条件
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
数据库执行执行此查询的时候,首先处理子查询,找出CS系中所有学生的年龄,找出一个集合(18,22)。任何处理父查询,找出所有不是CS系并且年龄小于18或22的学生即可。
本查询也可以用聚集函数来实现。首先用子查询查出CS系中最大年龄(22),任何在父查询中找出所有非CS系并且年龄小于22岁的学生即可。
select sname,sage
from student
where sage <
(select max(sage)from studentwhere sdept='CS'
) and sdept<>'CS'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
也可以得到上面的结构。结果如下:
【例6】查询其他系中比计算机科学系所有学生年龄都小的学生姓名和年龄
经过上面的分析,这个很简单,如下
select sname,sage
from student
where sage <all
(select sagefrom studentwhere sdept='CS'
) and sdept<> 'CS';
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
这里需要向大家说声对不起,刚开始构建数据的时候,没有构建好,所以这里查询为空,为了试验的完整性,我这里修改一下数据结构。
update student set sage=17 where sname='XiaoZhang';
- 1
ok,我们现在在执行刚才的操作,可以得到如下结果。
本查询也可以使用聚集查询来实现,如下:
select sname,sage
from student
where sage <
(select min(sage)from studentwhere sdept='CS'
) and Sdept !='CS';
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
事实上,聚集函数实现子查询通常比直接用all或any的效率更好。对应关系表如下:
四。带有exists谓词的子查询
带有exists谓词的子查询不返回任何数据,只产生逻辑真或假,也就是true或false。
【例6】查询所有选修了1号课程的学生姓名
select sname
from student
where exists
(select *from scwhere Sno=Student.Sno and Cno=1
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
那上面的执行流程是怎么样的呢?
①从外查询student表中取出一行数据
②把这条数据的Sno和内查询Sc表中的Sno进行比较
③若比较结果为真,则把这数据的sname放入一个结果集合中。
④然后再取student表的吓一条数据,直到取完为止。
使用exists量词后,若内存结果非空,则外层的where字句返回真值,否则返回假值。
由于exists引出的子查询,起目标列表达式通常都是“*”,因为带有exists的子查询只返回true或false,给出列名无具体意思。
exists谓词相对应的是not exists。使用not exists后,如果内存查询结果为空,则外层的where字句返回真值,否则返回假值。
【例7】查询没有选修了1号课程的学生姓名
select sname
from student
where not exists
(select *from scwhere Sno=Student.Sno and Cno=1
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
一些带exists或not exists谓词的子查询不能被其他形式的子查询等价替换,但是其他带有in谓词、比较运算符、any、all谓词的子查询都能用exists谓词的子查询替换。
Oracle数据库的嵌套查询相关推荐
- column ambiguously defined oracle数据库分页语句查询中select嵌套时出错
column ambiguously defined &oracle数据库分页语句查询中select嵌套时出错 转载于 [ lev草梦的博客](http://blog.sina.com.cn/ ...
- Oracle数据库:子查询、单行子查询,多行子查询,in,any,all语句,子查询的练习案例
Oracle数据库:子查询.单行子查询,多行子查询,in,any,all语句,子查询的练习案例 2022找工作是学历.能力和运气的超强结合体,遇到寒冬,大厂不招人,可能很多算法学生都得去找开发,测开 ...
- MySql实验嵌套查询_实验五 数据库的嵌套查询实验
实验五数据库的嵌套查询实验 本实验需要2学时. 一.实验目的 使学生进一步掌握SQL Server或oracle的企业管理器的使用方法,加深SQL 语言的嵌套查询语句的理解. 二.实验内容 在SQL ...
- sql镶嵌查询_sql数据库的嵌套查询
实验四:数据库的嵌套查询实验 学号: 姓名: 实验四:数据库的嵌套查询实验 实验目的: 加深对嵌套查询语句的理解. 实验内容: 使用 IN . 比较符. ANY 或 ALL 和 EXISTS 操作符进 ...
- Oracle数据库日期范围查询的两种实现方式
Oracle数据库日期范围查询有两种方式:to_char方式和to_date方式,接下来我们通过一个实例来介绍这一过程.我们假设要查询2011-05-02到2011-05-30之间的数据,实现方式如下 ...
- Oracle数据库之子查询
Oracle数据库总结: Oracle数据库之基本查询 Oracle数据库之过滤和排序 Oracle数据库之单行函数 Oracle数据库之多行函数 Oracle数据库之多表查询 SQL> 注意的 ...
- Oracle数据库之基本查询
oracle安装参照: Oracle数据库之安装教程 Oracle数据库总结: Oracle数据库之基本查询 Oracle数据库之过滤和排序 Oracle数据库之单行函数 Oracle数据库之多行函数 ...
- oracle数据库元数据SQL查询
oracle数据库经典SQL查询 1.查看表空间的名称及大小 select t.tablespace_name, round(sum(bytes/(1024*1024)),0) ts_size fro ...
- Oracle数据库Date类型查询问题(
浅谈Oracle数据库Date类型查询问题 用过Oracle数据库的朋友应该知道,Oracle数据库在以Date类型为查询条件时存在一个小小的BUG,如: select * from tableNam ...
最新文章
- python制作动态条形图-python – 动态更新matplotlib中的条形图
- 大厂面试必问!50w字+的Java技术类校招面试题汇总
- 【转】刨根究底字符编码之四——EASCII及ISO 8859字符编码方案
- Sublime Text一个小插件——SideBarEnhancements
- javascript 正则
- Ubuntu网卡驱动安装
- ftp误删服务器文件恢复,ftp服务器文件误删
- 常用的抓包工具有哪些?
- ddl是什么意思网络语_大学赶ddl是什么意思?DDL语句有什么功能?
- TI C66x DSP 系统events及其应用 - 1
- 中国都市女性抗衰洞察:Z世代抗衰意识普遍觉醒,“纹”题成抗衰重点
- 苹果与希捷 到底谁的错
- 工作第十六七周:生活这么繁琐,我们还要努力爱她
- RK3399 Android7.1修改安兔兔等读到的cpu最大频率为1.992GHz
- 【005】Nginx学习笔记-Nginx真实IP
- mysql概念模型中的3种基本联系_在概念模型中,通常用实体联系图表示数据的结构,其 3 个要的元素是( )、( )和( )。_学小易找答案...
- vs为什么打了断点不断_2019年亚洲羽毛球锦标赛半决赛焦点对阵:陈雨菲vs山口茜 德查波/莎西丽vs王懿律/黄东萍 周天成vs石宇奇...
- 数字图像处理与应用——图像和视频压缩技术
- 一招解决win11系统字体模糊发虚不清楚的问题
- mysql_check_mysql CHECK约束 语法
热门文章
- 因子分解机(FM)家族
- linux 安装到usb设备,如何通过 USB 设备来安装 CentOS
- 百度云虚拟服务器win,百度云- 使用xshell连接windows服务器
- [附源码]计算机毕业设计JAVA宠物狗领养网站
- C语言小明申请QQ号码
- 腾讯企业邮箱免费注册及登录方法
- 第三天python作业题
- Tita 绩效宝:绩效面谈的8个流程
- QQ欢乐豆斗地主心得体会(四):合谋赢豆
- mysql中如何分页查询_MySQL_mysql分页原理和高效率的mysql分页查询语句,以前我在mysql中分页都是用的 l - phpStudy...