5.oracle子查询


子查询;
N行N列概念:
1.单行单列:无论在行上还是列上都只有一个
2.单行多列:查询结果仅有一行数据,但是在列上不知一列
3.多行单列:查询结果仅有一列数据,但是行数上不止一行
4.多行多列:无论在行上还是列上都不知一个

表格解析:
SELECT          FROM          WHERE           GROUP BY             HAVING         ORDER BY
单行单列      单行单列       单行单列         不允许              单行单列         单行单列(无意义)
              单行多列       单行多列                             单行多列
              多行单列       多行单列                             多行单列
              多行多列       多行多列                             多行多列

子查询定义: 在一个查询语句中嵌入其他查询语句
子查询用途:查询作为一个集合跟在from,where 和 having子句中最多,还可以用在DML语句中;
--子查询中如果有null值,就不能使用NOT IN 运算符
SELECT ENAME FROM EMP WHERE MGR=(select empno FROM EMP WHERE ENAME='BLAKE');
SELECT ENAME FROM EMP WHERE MGR=(SELECT MGR FROM EMP WHERE ENAME='BLAKE');
SELECT EMPNO FROM EMP WHERE MGR=(SELECT MGR FROM EMP WHERE ENAME='BLAKE');
select * from emp where sal=(select max(sal) from emp);

select deptno from EMP where ename in ('SMITH','ALLEN');
SELECT * FROM EMP WHERE DEPTNO IN (select deptno from EMP where ename in ('SMITH','ALLEN'));

SELECT DEPTNO,SAL FROM EMP WHERE ENAME='SMITH';
SELECT * FROM EMP WHERE (DEPTNO,SAL)=(SELECT DEPTNO,SAL FROM EMP WHERE ENAME='SMITH') AND ENAME!='SMITH';

SELECT AVG(SAL) FROM EMP;
SELECT deptno FROM EMP GROUP BY DEPTNO HAVING AVG(SAL)>(SELECT AVG(SAL) FROM EMP);

select deptno from emp group by deptno having count(ename)>0;
select * from emp where deptno in (select deptno from emp group by deptno having count(ename)>0);

--子查询作为数据源时,当子查询语句中某字段出现了函数,需要对该字段起别名才能被主查训引用
select * from (select max(sal) as sal_max from emp) where sal_max=5863;

select round(avg(sal)) sal_avg,deptno from emp group by deptno;
SELECT max(sal_avg) FROM (select round(avg(sal)) sal_avg,deptno from emp group by deptno);
select deptno from (select round(avg(sal)) sal_avg,deptno from emp group by deptno) 
where sal_avg=(SELECT max(sal_avg) FROM (select round(avg(sal)) sal_avg,deptno from emp group by deptno));

select ename,job,sal,(select dname from dept where deptno=10) as dname
,(select loc from dept where deptno=10) as loc from emp where deptno=10;

--子查询的分类select ename from emp e1 where
/*非相关子查询: 子查询语句能够单独运行,子查询中不牵扯主查训的任何内容,主查训在乎的是与子查询的结果
相关子查询:   子查询语句不能单独运行,子查询牵扯主查训中的一部分内容,主查训只在乎与子查询的关系
非相关子查询可以用在任何位置,相关子查询京用于where和having中作为条件,且绝大多数情况两者可相互转换,
非相关子查询在书写和理解上更加容易,而相关子查询之所以存在,是因为很多情况下相关子查询运行效率更高
*/


相关子查询的关键词:
      exists 对应条件查询中的 in
      not exists  对应条件查询中的 not in;
      
相关子查询:执行查询的时候先取得外层查询的一个属性值,然后执行与此属性值相关的子查询,执行完毕后再取得外
            层父查询的下一个值,依次再来重复执行子查询;
不相关子查询:子查询的执行不需要提前取得父查询的值,只是作为父查询的查询条件

--两者区别
/*查询同样的数据,不同的方法,效率不同
两者都能实现表功能查询,主要区别如下:
1、适用表的类型不同。
in是子查询为驱动表,外面的表为被驱动表,故适用于子查询结果集小而外面的表结果集大的情况。
exists是外面的表位驱动表,子查询里面的表为被驱动表,故适用于外面的表结果集小而子查询结果集大的情况。

2、子查询关联不同。
exists一般都是关联子查询。对于关联子查询,必须先执行外层查询,接着对所有通过过滤条件的记录,执行内层查询。
       外层查询和内层查询相互依赖,因为外层查询会把数据传递给内层查询。
in     则一般都是非关联子查询,非关联子查询则必须先完成内层查询之后,外层查询才能介入。

3、执行次数不同。
IN 语句:只执行一次,确定给定的值是否与子查询或列表中的值相匹配。in在查询的时候,首先查询子查询的表,
         然后将内表和外表做一个笛卡尔积,然后按照条件进行筛选。所以相对内表比较小的时候,in的速度较快。
EXISTS语句:执行次数根据表的长度而定。指定一个子查询,检测行的存在。遍历循环外表,然后看外表中的记录有
            没有和内表的数据一样的。匹配上就将结果放入结果集中。*/
            
===EXISTS 相当于看子查询是否有返回结果,有则为 true 保留外表的该行作为结果,没有则返回 false 去除外表该行===;
SELECT * FROM EMP WHERE DEPTNO IN (SELECT DEPTNO FROM EMP WHERE ENAME='SMITH');
SELECT * FROM EMP E1 WHERE EXISTS (SELECT 1 FROM EMP E2 WHERE ENAME='SMITH' AND E2.DEPTNO=E1.DEPTNO);

select ename from emp e1 where exists (select 1 from emp e2 where ename='BLAKE' and e1.mgr=e2.empno);
select ename from emp  where mgr=(select empno from emp where ename='BLAKE');


在多行子查询中,我们有三个关键字,分别是:
     IN:在…之间
     ANY:任意一个
2.1:>ANY:比最小值大
2.2:<ANY:比最大值小
2.3:=ANY:跟IN一样的用法
      ALL:全部
3.1:>ALL:比最大的还大
3.2:<ALL:比最小的还小;












































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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值