oracle双重判断,Oracle!你必须要知道的Knowledge points(二)

子查询

什么是子查询

60737b32bbf2313a8f059872d603f778.png

当查询中的限制条件需要另一个查询提供时,我们可以把两个查询语句嵌套起来,提供条件的查询语句作为子查询。

子查询,也叫内部查询,先于主查询执行,子查询的结果被用于主查询。

子查询分为单行子查询、多行子查询和多列子查询,单行子查询作为判断条件时用单行运算符,多行子查询和多列子查询作为判断条件时用多行运算符。

单行运算符:>、=、>=、、<=

多行运算符:in、all、any

子查询可以嵌套在哪里

Where子句:作为非分组函数筛选判断的条件

From子句:将子查询的查询结果作为一张表来使用

Having子句:作为分组函数筛选判断的条件

子查询使用规范

子查询需要用括号括起来

当子查询放在from子句中时,是将查询到的结果作为一张表来使用,需给别名

单行子查询用单行运算符,多行子查询用多行运算符

子查询放在运算符右边

单行子查询

单行子查询返回一行一列,使用单行运算符进行连接

--显示和雇员7369从事相同工作并且工资大于雇员7876的雇员的姓名和工作。

select ename,job

from emp

where job = (select job from emp where empno =7369)

and sal > (select sal from emp where empno = 7876);

--查询工资最低的员工姓名,岗位及工资(子查询中使用了分组函数)

select ename,job,sal

from emp

where sal = (select min(sal) from emp)

--查询部门最低工资比20部门最低工资高的部门编号及最低工资(子查询嵌套在having子句)

select deptno,min(sal)

from emp

group by deptno

having min(sal) > (select min(sal) from emp where deptno = 20 );

多行子查询

多行子查询返回一行或多行记录,使用多行运算符进行连接

--查询是经理的员工姓名、工资

select ename,sal

from emp

where empno in (select mgr from emp)

ANY的使用

表示和子查询的任意一行结果进行比较,有一个满足条件即可。

any:大于子查询结果的任意一个,即大于最小值即可。

=any:等于子查询结果的任意一个,即等一任意一个即可,相当于in。

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

--查询部门编号不为10,且工资比10部门任意一名员工工资高的员工编号,姓名,职位,工资。

select empno,ename,job,sal

from emp

where deptno <> 10 and sal > any(select sal from emp where deptno = 10);

ALL的使用

表示和子查询的所有行结果进行比较,每一行必须都满足条件。

>all:表示大于子查询结果集中的所有行,即大于最大值。

= all :表示等于子查询结果集中的所有行,即等于所有值。

238cf9fc0a546ef2462f58f45aab7f6e.png

--查询部门编号不为10,且工资比10部门所有员工工资低的员工编号,姓名,职位,工资。

select empno,ename,job,sal

from emp

where deptno <> 10 and sal > all(select sal from emp where deptno = 10);

多列子查询

在一个表达式内同时和子查询的多个列进行比较,即子查询返回的记录含多列

33f5ecdc266c5272257279644613b2ce.png

--查询和1981年入职的任意一个员工的部门和职位完全相同员工姓名、部门、职位、入职日期,不包括1981年入职员工。

select ename,deptno,job,hiredate

from emp

where (deptno,job) in (select deptno,job from emp where to_char(hiredate,'YYYY') = '1981')

and to_char(hiredate,'YYYY') <> '1981';

51269da2f54a5aaafb2324001cf70788.png

--查询和1981年入职的任意一个员工的部门或职位相同员工姓名、部门、职位、入职日期,不包括1981年入职员工

select ename,deptno,job,hiredate

from emp

where job in (select job from emp where to_char(hiredate,'YYYY') = '1981')

or deptno in (select deptno from emp where to_char(hiredate,'YYYY') = '1981')

and to_char(hiredate,'YYYY') <> '1981';

子查询中的空值

子查询结果中含有空值对主查询会有怎样的影响?

365732f3b7aa62fd306b477a9f70e2c4.png

--查询不是经理的员工姓名

select ename

from emp

where empno not in (select mgr from emp);

73e2ab531aaf3308d2ade8f11b1f5cb4.png

子查询的结果中有一条空值,这条空值导致主查询没有记录返回,这是因为所有的条件和空值比较结果都是空值,因此无论什么时候只要空值

有可能成为子查询结果集合中的一部分,就不能使用 not in 运算符。

如果子查询的结果中包含空值,又想使用 not in 运算符该怎么办?

--查询不是经理的员工姓名

select ename

from emp

where empno not in (select nvl(mgr,0) from emp); --使用nvl()函数去除空值影响

6b5f4fbcf9f141c817338cf6b4ef88bb.png

在from子句中使用子查询

在from子句中使用子查询,相当于把子查询的查询结果作为一张表来使用,在使用时建议加上相应的别名

--查询比自己部门平均工资高的员工姓名,工资,部门编号,部门平均工资

select e.ename,e.sal,e.deptno,w.avgsal

from emp e,(select avg(sal) as avgsal deptno from emp group by deptno) w

where e.deptno = w.deptno and e.sal > w.avgsal;

ROWNUM

rownum是一个伪列,顾名思义,就是一个类似于表中的列,而实际并没有存储在表中的特殊列;

rownum的功能是在每次查询时,返回结果集的顺序号,这个顺序号是在记录输出时才一步一步产生的,第一行显示为1,第二行为2,以此类推。

select rownum.emp.* from emp;

e548ec78ecc474835dccd071cc58abc2.png

关于rownum需要知道的几点

rownum是在记录输出时才生成,且总是从1开始

rownum只能执行、>= 或区间运算between ... and ...

rownum和order by一起使用时,因为rownum在记录输出时生成,而order by子句在最后执行,所以当两者一起使用时,需要注意rownum实际是已经被排了序的rownum。

TOP-N查询

实现表中按照某个列排序,输出最大或最小的N条记录功能

Top-N语法

d92edb169f802de999ae439e8e21a119.png

ASC:升序排序,查询最小的N条记录

DESC:降序排序,查询最大的N条记录

238cf9fc0a546ef2462f58f45aab7f6e.png

--查询入职日期最早的前5名员工姓名,入职日期。

select rownum,ename,hiredate

from (select ename,hiredate from emp order by hiredate)

where rownum <= 5;

7c6373cf210e8a5c56f0220c2327f6a1.png

--查询工作在CHICAGO并且入职日期最早的前2名员工姓名,入职日期

select rownum,ename,hiredate

from (select ename,hiredate from emp

where deptno = (select deptno from dept where loc = 'CHICAGO')

order by hiredate)

where rownum <= 2;

8237e28711e976f227e6b4aa3001d743.png

分页查询

利用ROWNUM的特性,可以实现数据库端的分页查询

语法格式

a7b77b5cb01c943f615cd28b565bd42b.png

--按照每页显示5条记录,分别查询第1页,第2页,第3页信息,要求显示员工姓名、入职日期、部门名称。

select b.*

from (select rownum rn,ename,hiredate,dname

from emp,dept

where emp.deptno = dept.deptno and rownum <= 1*5) b

where rn > (1-1)*5;

213cae4166253e42e704c202e26dc33d.png

select b.*

from (select rownum rn,ename,hiredate,dname

from emp,dept

where emp.deptno = dept.deptno and rownum <= 2*5) b

where rn > (2-1)*5;

13a6957d7b5f2c94b9bd4e9552a38288.png

select b.*

from (select rownum rn,ename,hiredate,dname

from emp,dept

where emp.deptno = dept.deptno and rownum <= 3*5) b

where rn > (3-1)*5;

76fa7c8da1e727925691d864c7c135e5.png

排序后分页

dd82756f863dca6b7068d4306daaa8a5.png

排序->rownum->select输出最后结果

--按照每页显示5条记录,分别查询工资最高的第1页,第2页,第3页信息,要求显示员工姓名、入职日期、部门名称、工资。

select *

from (select rownum rn,b.*

from (select ename,hiredate,dname,sal from emp,dept

where emp.deptno = dept.deptno

order by sal desc) b

where rownum <= 1*5 )

where rn > (1-1) * 5;

79349766aac7c3f6ecb523529fa2beea.png

select *

from (select rownum rn,b.*

from (select ename,hiredate,dname,sal from emp,dept

where emp.deptno = dept.deptno

order by sal desc) b

where rownum <= 2*5 )

where rn > (2-1) * 5;

76b5751b2806a3cacba03779d5a9e1de.png

select *

from (select rownum rn,b.*

from (select ename,hiredate,dname,sal from emp,dept

where emp.deptno = dept.deptno

order by sal desc) b

where rownum <= 3*5 )

where rn > (3-1) * 5;

44ac3e32db59c5dcc217f4529d7adc8a.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值