东软实习之数据库(7)——子查询
##子查询
括号内的查询叫做子查询,也叫内部查询,先于主查询执行。
子查询的结果被主查询(外部查询)使用 Expr operator包括比较运算符。
-
-
- 单行运算符:>、=、>=、<、<>、<=
- 多行运算符: IN、ANY、ALL
-
子查询可以嵌于以下SQL子句中:
- WHERE子句
- HAVING子句
- FROM子句
子查询使用指导
-
-
- 子查询要用扩号扩起来
- 将子查询放在比较运算符的右边
- 在子查询中的ORDER BY 子句不需要,除非你正在执行Top-N分析
- 对于单行子查询要使用单行运算符
- 对于多行子查询要使用多行运算符
-
#子查询类型
#单行子查询
单行子查询
-
- 子查询只返回一行一列
- 使用单行运算符
-
- 子查询中使用组函数
查询工资最低的员工姓名,岗位及工资
-
-
HAVING子句中使用子查询
-
查询部门最低工资比20部门最低工资高的部门编号及最低工资
#多行子查询
多行子查询,子查询返回记录的条数可以是一条或多条。
多行子查询需要使用多行操作符。
常用的多行操作符包括:
-
- IN
- ANY
- ALL
IN操作符和以前介绍的功能一致,判断是否与子查询的任意一个返回值相同。返回的结果可以是一条或多条。
#IN
#ANY:表示任意的。
< ANY 比子查询返回的任意一个结果小即可,即小于返回结果的最大值。
= ANY 和子查询中任意一个结果相等即可,相当于IN。
> ANY比子查询返回的任意一个结果大即可,即大于返回结果的最小值。
#ALL:表示所有的。
< ALL 比子查询返回的所有的结果都小,即小于返回结果的最小值。
> ALL比子查询返回的所有的结果都大,即大于返回结果的最大值。
= ALL 无意义,逻辑上也不成立。
##多列子查询
到目前为止您已经能完成单行和多行子查询,但是都是只有一个列在SELECT语句的WHERE或HAVING子句中进行比较。
如果想多个列进行比较呢,您必须使用逻辑运算符编写一个复合WHERE子句。
多列子查询可以让您将WHERE子句中多个条件合并成一个
多列比较
成对比较与非成对比较
多列子查询中的列比较有成对比较与不成对比较两种
-
-
- 成对比较表示每一个候选行上被比较的列 必须和子查询所返回的任何一行两个列相等;
- 不成对比较实际上是多个条件拼装在一起的WHERE子句。
-
成对比较
不成对比较
子查询中的空值
子查询返回的结果中含有空值
上面的SQL语句试图查找出没有下属的雇员,逻辑上,这个SQL语句应该会返回8条记录,但是却一条也没返回。
子查询的结果中有一条空值,这就导致主查询没有记录返回。这是因为所有的条件和空值比较结果都是空值。
因此无论什么时候只要空值有可能成为子查询结果集合中的一部分,就不能使用NOT IN 运算符。
NOT IN 运算符等效于<>ALL。.
注意,如果您使用IN运算符的话空值有成为子查询结果集合中的一部分并不会有什么问题。IN运算符等效于=ANY
在 FROM 子句中使用子查询
##分页
ROWNUM
ROWNUM是一个伪列,伪列是使用上类似于表中的列,而实际并没有存储在表中的特殊对象;
ROWNUM的功能是在每次查询时,返回结果集的顺序数,这个顺序数是在记录输出时才一步一步产生的,第一行显示为1,第二行为2,以此类推。
ROWNUM使用的注意点:
- ROWID与ROWNUM都被称为伪列,但它们的存在方式是不一样的,ROWID,是物理存在的,表示记录在表空间中的唯一位置ID,在DB中是唯一的。只要记录没被搬动过,ROWID是不变的,而ROWNUM是在查询结果输出时才生成。
- 如下SQL语句,SELECT * FROM EMP WHERE ROWNUM>2;查询不到任何记录,因为ROWNUM是在记录输出时才生成,且总是从1开始,所以第一条记录不满足>2的条件,被去掉,第二条的ROWNUM又成了1。依此类推,所以永远没有满足条件的记录,所以对于ROWNUM只能执行<、<=运算,不能执行>、>=或一个区间运算Between..And等
- ROWNUM和ORDER BY一起使用时,因为ROWNUM在记录输出时生成,而ORDER BY子句在最后执行,所以当两者一起使用时,需要注意ROWNUM实际是已经被排了序的ROWNUM。
#TOP-N查询
Top-N查询主要是实现表中按照某个列排序,输出最大或最小的N条记录功能。
Top-N分析语法:
ASC:查询最小的N条记录
DESC:查询最大的N条记录
#分页查询
在Oracle中,利用ROWNUM的特性,可以实现数据库端的分页查询,查询语法为:
- 当未指定需要按照某列排序,语法为:
- 当指定需要按照某列排序时,语法为:
##本章重点总结
-
-
- 为什么使用子查询
- 单行子查询
- 多行子查询
- 多列子查询
- 子查询中空值问题
- FROM语句中子查询
- 分页查询
-