Oracle专题8之Oracle的子查询

前端之家收集整理的这篇文章主要介绍了Oracle专题8之Oracle的子查询前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1、Oracle的子查询的概述

  • 什么是子查询
  • 查询是指嵌入在其他sql语句中的SELECT语句,也称之为嵌套查询
  • 可以使用子查询的位置:where、select列表、having、from。

a、在where子句中使用子查询

  • 示例:查询出和FORD是相同职位的员工:select * from emp where job = (select job from emp where ename='FORD');
  1. sql> select * from emp where job = (select job from emp where ename='FORD');
  2. EMPNO ENAME JOB MGR HIREDATE SAL COMM
  3. DEPTNO
  4. 7951 EASON ANALYST 7566 01-12月-17 3000
  5. 20
  6. 7788 SCOTT ANALYST 7566 19-4 -87 3000
  7. 20
  8. 7902 FORD ANALYST 7566 03-12月-81 3000
  9. 20

b、在select子句中使用子查询

  • 示例:查询出每个部门的编号、名称、位置和部门人数。示例:select deptno,dname,loc,(select count(empno) from emp where emp.deptno = dept.deptno) count from dept;
  1. sql> select deptno,(select count(empno) from emp where emp.deptno = dept.deptno) count from dept;
  2. DEPTNO DNAME LOC COUNT
  3. 10 ACCOUNTING NEW YORK 3
  4. 20 RESEARCH DALLAS 6
  5. 30 SALES CHICAGO 6
  6. 40 OPERATIONS BOSTON 0

c、在having子句中使用子查询

  • 举例:查询员工信息表,按照部门编号进行分组,要求显示员工的部门编号、平均工资,查询条件时平均工资大于30号部门的最高工资。
  1. sql> select deptno,avg(sal) from emp group by deptno having avg(sal) > (select max(sal) from emp where deptno = 30);
  2. DEPTNO AVG(SAL)
  3. 10 2916.66667

d、在from子句中使用子查询

  • 把子查询的结果看成一张新的表。示例:查询显示高于部门平均工资的雇员信息。
  1. sql> select ename,job,sal from emp,(select deptno,avg(sal) avgsal from emp group by deptno) dept where emp.deptno = dept.deptno and sal > avgsal;
  2. ENAME JOB SAL
  3. EASON ANALYST 3000
  4. ALLEN SALESMAN 1600
  5. JONES MANAGER 2975
  6. BLAKE MANAGER 2850
  7. SCOTT ANALYST 3000
  8. KING PRESIDENT 5000
  9. FORD ANALYST 3000
  10. 已选择7行。

2、Oracle的主查询和子查询

a、一个主查询可以有多个子查询

  • 举例:显示职位和7521的职位相同并工资大于7934这个员工工资的员工信息。
  1. sql> select * from emp where job = (select job from emp where empno = 7521) and sal > (select sal from emp where empno = 7934);
  2. EMPNO ENAME JOB MGR HIREDATE SAL COMM
  3. DEPTNO
  4. 7499 ALLEN SALESMAN 7698 20-2 -81 1600 300
  5. 30
  6. 7844 TURNER SALESMAN 7698 08-9 -81 1500 0
  7. 30

b、子查询的执行顺序

  • 一般先执行子查询,再执行主查询,但相关子查询例外。
  • 举例:查询员工表中小于平均工资的员工信息。
  1. sql> select empno,ename,sal from emp where sal < (select avg(sal) from emp);
  2. EMPNO ENAME SAL
  3. 7369 G_EASON 800
  4. 7499 ALLEN 1600
  5. 7521 WARD 1250
  6. 7654 MARTIN 1250
  7. 7844 TURNER 1500
  8. 7876 ADAMS 1100
  9. 7900 JAMES 950
  10. 7934 MILLER 1300
  11. 已选择8行。

c、相关子查询

  • 当子查询需要引用主查询的表列时,Oracle会执行相关查询
  • 相关子查询是先执行主查询,在执行子查询
  • 示例:查询工资高于部门平均工资的雇员名、工资和部门号:
  1. sql> select ename,sal,deptno from emp e where sal > (select avg(sal) from emp where deptno = e.deptno);
  2. ENAME SAL DEPTNO
  3. EASON 3000 20
  4. ALLEN 1600 30
  5. JONES 2975 20
  6. BLAKE 2850 30
  7. SCOTT 3000 20
  8. KING 5000 10
  9. FORD 3000 20
  10. 已选择7行。

d、主查询和子查询可以不是同一张表

  1. sql> select * from emp where deptno = (select deptno from dept where dname='ACCOUNTING');
  2. EMPNO ENAME JOB MGR HIREDATE SAL COMM
  3. DEPTNO
  4. 7782 CLARK MANAGER 7839 09-6 -81 2450
  5. 10
  6. 7839 KING PRESIDENT 17-11月-81 5000
  7. 10
  8. 7934 MILLER CLERK 7782 23-1 -82 1300
  9. 10

3、Oracle的子查询:单行子查询

  • 查询的类型:单行子查询和多行子查询
  • 单行子查询:只返回一行数据的子查询语句。
  • 使用单行比较操作符:
操作符 含义
= 等于
> 大于
>= 大于等于
< 小于
<= 小于等于
<> 不等于

a、使用单行子查询

  • 示例1:显示与JAMES同部门的所有其他的员工姓名、工资、部门号。
  1. sql&gt; select ename,deptno from emp where deptno = (select deptno from emp where ename='JAMES') AND ename &lt;&gt; 'JAMES';
  2. ENAME SAL DEPTNO-
  3. ALLEN 1600 30
  4. WARD 1250 30
  5. MARTIN 1250 30
  6. BLAKE 2850 30
  • 示例2:查询大于等于公司平均工资的员工的姓名、职位、工资。
  1. sql&gt; select ename,sal from emp where sal &gt;= (select avg(sal) from emp);
  2. ENAME JOB SAL
  3. EASON ANALYST 3000
  4. JONES MANAGER 2975
  5. BLAKE MANAGER 2850
  6. CLARK MANAGER 2450
  7. SCOTT ANALYST 3000
  8. KING PRESIDENT 5000
  9. FORD ANALYST 3000
  10. 已选择7行。
  1. sql&gt; select * from emp where deptno &lt;&gt; (select deptno from dept where dname= 'SALES');
  2. EMPNO ENAME JOB MGR HIREDATE SAL COMM
  3. DEPTNO
  4. 7951 EASON ANALYST 7566 01-12月-17 3000
  5. 20
  6. ......
  7. 7902 FORD ANALYST 7566 03-12月-81 3000
  8. 20
  9. 7934 MILLER CLERK 7782 23-1 -82 1300
  10. 10
  11. 已选择9行。

b、非法使用单行子查询

  • 示例:select ename,sal from emp where sal = (select max(sal) from emp group by deptno);
  1. sql&gt; select ename,sal from emp where sal = (select max(sal) from emp group by deptno);
  2. select ename,sal from emp where sal = (select max(sal) from emp group by deptno)
  3. 1 行出现错误:
  4. ORA-01427: 单行子查询返回多个行
  • select max(sal) from emp group by deptno;sql语句返回多行数据。
  1. sql&gt; select max(sal) from emp group by deptno;
  2. MAX(SAL)
  3. 2850
  4. 3000
  5. 5000

4、Oracle的子查询:多行子查询

  • 多行子查询是指返回多行数据的子查询语句。
  • 使用多行比较操作符:(使用多行子查询时必须使用多行比较操作符。)
运算符 含义
IN 等于列表中的任何一个
ALL 和子查询返回的所有值进行比较
ANY 和子查询返回的任一值进行比较

a、在多行子查询中使用IN操作符

  • 示例:查询工作地点在NEW YORK和CHICAGO的部门所对应的员工信息。
  1. sql&gt; select * from emp where deptno in (select deptno from dept where loc='NEW YORK' or loc = 'CHICAGO');
  2. EMPNO ENAME JOB MGR HIREDATE SAL COMM
  3. DEPTNO
  4. 7934 MILLER CLERK 7782 23-1 -82 1300
  5. 10
  6. ......
  7. 7698 BLAKE MANAGER 7839 01-5 -81 2850
  8. 30
  9. 7654 MARTIN SALESMAN 7698 28-9 -81 1250 1400
  10. 30
  11. 已选择9行。

b、在多行子查询中使用ALL操作符

  • 示例:查询高于30号部门所有员工工资的员工名、工资和部门号。
  1. sql&gt; select ename,deptno from emp where sal &gt; all(select sal from emp where deptno = 30);
  2. ENAME SAL DEPTNO
  3. JONES 2975 20
  4. EASON 3000 20
  5. FORD 3000 20
  6. SCOTT 3000 20
  7. KING 5000 10

c、在多行子查询中使用ANY操作符

  • 示例:查询高于10号部门任意一个员工工资的员工名、工资和部门号。
  1. sql&gt; select ename,deptno from emp where sal &gt; any (select sal from emp where deptno = 10);
  2. ENAME SAL DEPTNO
  3. KING 5000 10
  4. EASON 3000 20
  5. ......
  6. ALLEN 1600 30
  7. TURNER 1500 30
  8. 已选择9行。
  9. ```
  10. # 5、Oracle的子查询需要注意的问题
  11. ## a、不可以在group by子句中使用子查询
  12. - 示例:select avg(sal) from emp group by (select deptno from emp);
  1. sql&gt; select avg(sal) from emp group by (select deptno from emp);
  2. select avg(sal) from emp group by (select deptno from emp)
  3. 1 行出现错误:
  4. ORA-22818: 这里不允许出现子查询表达式
  1. ## b、在TOP-N分析问题中,需对子查询排序
  2. - 示例:显示员工信息表中工资最高的前五名员工。
  1. sql&gt; select rownum,empno,sal from (select * from emp order by sal desc) where rownum &lt;= 5;
  2. ROWNUM EMPNO ENAME SAL
  3. 1 7839 KING 5000
  4. 2 7951 EASON 3000
  5. 3 7902 FORD 3000
  6. 4 7788 SCOTT 3000
  7. 5 7566 JONES 2975
  1. ## c、单行子查询的空值问题
  2. - 示例:select ename,from emp where job = (select job from emp wehre ename = 'Ruby');
  1. sql&gt; select ename,job from emp where job = (select job from emp where ename = 'Ruby');
  2. 未选定行
  3. ```
  • 如果子查询返回到的是一个空值,那么主查询将不会查询到任何结果。

d、多行子查询的空值问题

  • 示例:select * from emp where empno not in (select mgr from emp);
  1. sql&gt; select mgr from emp;
  2. MGR
  3. 7566
  4. null
  5. ......
  6. 7839
  7. 7566
  8. 7698
  9. 已选择15行。
  10. sql&gt; select * from emp where empno not in (select mgr from emp);
  11. 未选定行
  1. sql&gt; select * from emp where empno not in (select mgr from emp where mgr is not null);
  2. EMPNO ENAME JOB MGR HIREDATE SAL COMM
  3. DEPTNO
  4. 7844 TURNER SALESMAN 7698 08-9 -81 1500 0
  5. 30
  6. 7951 EASON ANALYST 7566 01-12月-17 3000
  7. 20
  8. ......
  9. 7934 MILLER CLERK 7782 23-1 -82 1300
  10. 10
  11. 7900 JAMES CLERK 7698 03-12月-81 950
  12. 30
  13. 已选择9行。

猜你在找的Oracle相关文章