Oracle 普通子查询和关联子查询

子查询(普通子查询和关联子查询)
子查询 = 简单查询 + 限定查询 + 多表查询 + 统计查询的综合体;
所谓子查询:指的就是在一个查询之中嵌套了其他的若干查询,嵌套子查询之后的查询SQL语句如下:
SELECT [DISTINCT] *|分组字段1 [别名] [,分组字段2 [别名] ,…] | 统计函数 ,(
      SELECT [DISTINCT] *|分组字段1 [别名] [,分组字段2 [别名] ,…] | 统计函数
      FROM 表名称 [别名], [表名称 [别名] ,…]
      [WHERE 条件(s)]
      [GROUP BY 分组字段1 [,分组字段2 ,…]]
      [HAVING 分组后的过滤条件(可以使用统计函数)]
      [ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]])
FROM 表名称 [别名], [表名称 [别名] ,…] ,(
      SELECT [DISTINCT] *|分组字段1 [别名] [,分组字段2 [别名] ,…] | 统计函数
      FROM 表名称 [别名], [表名称 [别名] ,…]
      [WHERE 条件(s)]
      [GROUP BY 分组字段1 [,分组字段2 ,…]]
      [HAVING 分组后的过滤条件(可以使用统计函数)]
      [ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]])
[WHERE 条件(s) (
      SELECT [DISTINCT] *|分组字段1 [别名] [,分组字段2 [别名] ,…] | 统计函数
      FROM 表名称 [别名], [表名称 [别名] ,…]
      [WHERE 条件(s)]
      [GROUP BY 分组字段1 [,分组字段2 ,…]]
      [HAVING 分组后的过滤条件(可以使用统计函数)]
      [ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]])]
[GROUP BY 分组字段1 [,分组字段2 ,…]]
[HAVING 分组后的过滤条件(可以使用统计函数)]
[ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]];
注意:理论上子查询可以出现在查询语句的任意位置上,但是实际开发运用中,子查询出现在WHERE和FROM子句之中较多

普通子查询
一般情况下:
WHERE:子查询一般只返回单行单列、多行单列、单行多列的数据;
FROM:子查询返回的一般是多行多列的数据,当作一张临时表出现。
HAVING:子查询返回的一般是单行单列数据。
子查询在 WHERE 中出现
1.返回 单行单列 数据
范例一: 查询出工资比SMITH还要高的全部雇员信息
SELECT * FROM EMP WHERE sal>(SELECT sal FROM EMP WHERE ename='SMITH');
2.子查询返回 单行多列 数据
以上所返回的是单行单列,但是在子查询之中,也可以返回单行多列的数据,只是这种子查询很少出现。
范例:查询出emp表中 职位和薪资 与雇员 'SCOTT'的 职位和薪资 相同的雇员信息。
SELECT * FROM EMP WHERE (JOB,SAL)=(SELECT job,sal from emp where ename='SCOTT');
3.子查询返回 多行单列 数据
如果现在的子查询返回的是多行单列数据的话,这个时候就需要使用三种判断符判断了:IN、ANY、ALL;

IN 操作符
IN里面的范围由子查询指定。
案例:查询雇员的工资等于在经理的工资的范围内的雇员信息
SELECT * FROM EMP WHERE SAL IN (SELECT SAL FROM EMP WHERE JOB='MANAGER');
但是在使用IN的时候还要注意 NOT IN的问题,如果使用NOT IN操作,在子查询之中,如果有一个内容是null,则不会查询出任何的结果。
解决非空 问题,使用空判断NVL。
SELECT * FROM EMP WHERE SAL IN (SELECT NVl(SAL,0) FROM EMP WHERE JOB='MANAGER');

ANY操作符:与每一个内容想匹配,有三种匹配形式
=ANY:功能与IN操作符是完全一样的;
案例:查询雇员的工资等于在经理的工资的范围内的雇员信息
SELECT * FROM EMP WHERE SAL =ANY(SELECT NVl(SAL,0) FROM EMP WHERE JOB='MANAGER');
>ANY:比子查询中返回记录最小的还要大的数据;
案例:查询雇员的工资比经理的工资高的雇员信息
SELECT * FROM EMP WHERE SAL >ANY(SELECT NVl(SAL,0) FROM EMP WHERE JOB='MANAGER');
<ANY:比子查询中返回记录的最大的还要小;
案例:查询雇员的工资比经理的工资低的雇员信息
SELECT * FROM EMP WHERE SAL <ANY(SELECT NVl(SAL,0) FROM EMP WHERE JOB='MANAGER');

ALL操作符:与每一个内容相匹配,有两种匹配形式:
需要注意的是:ALL 。(如果有一个内容是null,则不会查询出任何的结果。)
>ALL:比子查询中返回的最大的记录还要大
案例:查询雇员的工资比经理的任意一个工资高的雇员信息
SELECT * FROM EMP WHERE SAL >ALL(SELECT NVl(SAL,0) FROM EMP WHERE JOB='MANAGER');
<ALL:比子查询中返回的最小的记录还要小
案例:查询雇员的工资比经理的任意一个工资低的雇员信息
SELECT * FROM EMP WHERE SAL <ALL(SELECT NVl(SAL,0) FROM EMP WHERE JOB='MANAGER');

子查询在 FROM 中出现

这个子查询一般返回的是多行多列的数据,当作一张临时表的方式来处理。
范例:查询出每个部门的编号、名称、位置、部门人数、平均工资
SELECT
  d.DEPTNO 编号,
  d.DNAME  名称,
  d.LOC    位置,
  temp.c   部门人数,
  temp.a   平均工资
FROM DEPT d, (SELECT
                DEPTNO     dno,
                count(SAL) c,
                avg(SAL)   a
              FROM EMP
              GROUP BY DEPTNO) temp
WHERE d.DEPTNO = temp.dno;

子查询在 HAVING 中出现(一般在条件判断出现统计函数的时候才使用)

范例:查询出职位的名称、人数、平均薪资,且要求 职位平均薪资高于公司平均薪资的,查询结果根据平均薪资降序排列。
SELECT
  JOB          名称,
  count(ENAME) 人数,
  avg(SAL)     平均薪资
FROM EMP
GROUP BY JOB
HAVING avg(SAL) > (SELECT avg(sal)
                   FROM EMP)
ORDER BY 平均薪资 DESC;

关联子查询
关联子查询就是指子查询与主查询之间有条件关联,不能独自执行。而 普通子查询 的子查询语句可以单独执行。
对于关联子查询有以下要求:
被关联的 子查询不能返回多于1行的数据
范例一:查询雇员的领导不是经理的雇员的姓名、雇员部门、雇员薪资。
SELECT
  e.ENAME  雇员的姓名,
  e.DEPTNO 雇员部门,
  e.SAL    雇员薪资
FROM EMP e
WHERE 'MANAGER' <> (SELECT JOB
                    FROM EMP
                    WHERE EMPNO = e.MGR);

范例二:列出比本部门平均工资高的员工姓名,工资,职位,部门号。
SELECT
  e.ENAME  员工姓名,
  e.SAL    工资,
  e.job    职位,
  e.DEPTNO 部门号
FROM EMP e
WHERE e.SAL > (SELECT avg(SAL)
             FROM EMP
             WHERE e.DEPTNO = DEPTNO);

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值