Oracle SQL子查询笔记

 

    子查询是指嵌入在其他SQL语句中的SELECT语句,也称为嵌套查询。注意,当在DDL语句中引用子查询时,可以带有Order By子句;但是当在where子句、Set子句中引用子查询时,不能带有Order by 子句。子查询具有以下一些作用:

    1、通过在insert或create table语句中使用子查询,可以将源表数据插入目标表中。

    2、通过在create view或create materialieed view中使用子查询,可以定义视图或实体化视图所对应的select语句。

    3、通过在update语句中使用子查询可以修改一列或多列数据。

    4、通过在where、having、start with子句中使用子查询,可以提供条件值。

    根据子查询返回结果的不同,子查询又被分为单行子查询、多行子查询和多列子查询。

    一、单行子查询

    单行子查询是指只返回一行数据的子查询语句。当在where子句中引用单行子查询时,可以使用单行比较符(=、>、<、>=、<=、<>)。

    例:显示JONES同部门的姓名、工资和部门。

     sql代码:

     SELECT ename,sal,deptno FROM emp WHERE deptno=(SELECT deptno FROM emp WHERE ename='JONES');

    二、多行子查询

    多行子查询是指返回多行数据的子查询语句。当在where子句中使用多行子查询时必须要使用多行比较符(IN、ALL、ANY)。它们的作用如下: 

    IN:匹配于子查询结果的任一个值即可。

    ALL:必须要符合子查询结果的所有值。

    ANY:只要符合子查询结果的任一个值即可。

    注意,ALL和ANY操作符不能单独使用,而只能与单行比较符(=,>,<,>=,<=,<>)结合使用。

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

    当在多行子查询中使用IN操作符时,会处理匹配于子查询任一值的行。

    例:显示与部门10所有员工同工作的雇员名、岗位、工资、部门号的员工。

    sql代码:

    SELECT ename,job,sal,deptno FROM emp WHERE job IN (SELECT distinct job FROM emp WHERE deptno=10);

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

    ALL操作符必须与单行操作符结合使用,并且返回行必须要匹配于所有子查询结果。

    例:显示高于部门30所有雇员工资的雇员名、工资和部门号。

    sql代码:

    SELECT ename,sal,deptno FROM emp WHERE sal > all (SELECT sal FROM emp where deptno=30);

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

    ANY操作符必须与单行操作符结合使用,并且返回行只需匹配于子查询的任一个结果即可。

    例:显示高于部门30的任意雇员工资的雇员名、工资和部门号。

    sql代码:

    SELECT ename,sal,deptno FROM emp where sal > ANY (SELECT sal FROM emp WHERE deptno=30);

    三、多列子查询

    单行子查询是指子查询只返回单列单行数据,多行子查询是指子查询返回单列多行数据,二者都是针对单列而言的。而多列子查询则是指返回多列数据的子查询语句。当多列子查询返回单行数据时,在where子句中可以使用单行比较符;当多列子查询返回多行数据时,在where子句中必须使用多行比较符(IN、ANY、ALL)。

    例:显示与SMITH部门和岗位完全相同的所有雇员的雇员名,工作岗位、工资和部门号。

    SELECT ename,job,sal,deptno FROM emp WHERE (deptno,job) = (SELECT deptno,job FROM emp WHERE ename='SMITH');

 

    在使用子查询比较多个列的数据时,即可以使用成对比较,也可以使用非成对比较。其中,成对比较要求多个列的数据必须同时匹配,而非成对比较则不要求多个列的数据同时匹配。

    如下图:

    如图所示,当进行成对比较时,要求工资和补助必须同时匹配;而当执行非成对比较时,只要工资匹配于工资列表中的某一个、补助匹配于补助列表中的某一个就可以了。

    1、成对比较示例

     当执行成对比较时,因为要求多个列的数据必须同时匹配,所以必须要使用多列子查询实现。

    例:显示工资和补助与部门30雇员的工资和补助完全匹配的所有雇员。 

    sql代码:

    SELECT ename,sal,comm,deptno FROM emp  WHERE (sal,nvl(comm,-1)) IN (SELECT sal,nvl(comm,-1) FROM emp WHERE deptno=30);

    2、非成对比较示例

    执行非成对比较时,应该要使用多个多行子查询来实现。

    例:显示工资匹配于部门30工资列表、补助匹配于部门30补助列表的所有雇员。

    sql代码:

    SELECT ename,sal,comm,deptno FROM emp WHERE sal IN (SELECT sal FROM emp WHERE deptno=30) AND nvl(comm,-1) IN (select nvl(comm,-1) FROM emp WHERE deptno=30);

    四、其他子查询

    在where子句中除了可以使用单行子查询、多行子查询以及多列子查询外,还可以用相关子查询。另外在FORM子句、DML语句、DDL语句中也可以使用子查询。

    1、相关子查询

    相关子查询是指需要引用主查询表列的子查询语句,相关子查询是通过exists谓词来实现的。

    例:显示工作在"NEW YORK"的所有雇员。

    sql代码:

    SELECT ename,job,sal,deptno FROM emp WHERE EXISTS (SELECT 1 FROM dept WHERE dept.deptno=emp.deptno AND dept.loc='NEW YORK');

    2、在FROM子句中使用子查询

    当在FORM子句中使用子查询时,该子查询会被作为视图对待,因此也被称为内嵌视图。注意,当在FORM子句中使用子查询时,必须给子查询指定别名。  

    例:显示高于部门平均工资的雇员信息。

    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 > dept.avgsal;

    3、在DML语句中使用子查询

    子查询不仅适于SELECT语句,也适用于任何DML语句。

    (1)在insert语句中使用子查询

    通过在insert语句中引用子查询,可以将一张表的数据装载到另一张表中去。

    例:将EMP表的数据装载到EMPLOYEE表中。

    sql代码

    INSERT INTO employee(id,name,title,salary) SELECT empno,ename,job,sal FROM emp;

    (2)在update语句中使用子查询

    当在update语句中使用子查询时,即可以在where子句中引用子查询,也可以在SET子句中使用子查询(修改列数据)。

    例:将SMITH同岗位的雇员工资和补助更新为与SMITH的工资和补助完全相同。

    sql代码:

    UPDATE emp SET (sal,comm)=(SELECT sal,comm FROM emp WHERE ename='SMITH') WHERE job= (SELECT job FROM emp WHERE ename='SMITH');

'   (3)在delete语句中使用子查询

    在delete语句中使用子查询时,可以在where子句中引用子查询返回未知值。 

   例:删除SALES部门的所有雇员。

   sql代码

    DELETE FROM emp WHERE deptno= (SELECT deptno FROM dept WHERE dname='SALES');

    4、在DDL语句中使用子查询

    除了可以在select、insert、update、delete语句中使用子查询外,也可以在DDL语句中使用子查询。注意,当在select和dml语句中使用子查询时,where子句和set子句的子查询语句不能包含order by子句;但在DDL语句中使用子查询时,子查询可以包含Oorder by 子句。

    (1)在create table 语句中使用子查询

     通过在create table中使用子查询,可以在建立新表的同时复制表的数据。

     例:建立new_emp表,并将emp表的数据复制到该表。

     CREATE TABLE new_emp(id,name,sal,job,deptno) AS SELEct empno,ename,sal,job,deptno FROM emp;

     (2)在create vies语句中使用子查询

     建立视图时,必须指定视图所对应的子查询语句。

     CREATE OR REPLACE  VIEW dept_10 AS SELECT empno,ename,job,sal,deptno FROM emp WHERE deptno=10 ORDER BY empno; 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值