SQL 基础--> 子查询

–=========================

–SQL 基础–> 子查询

–=========================  

 

/*

一、子查询

    子查询就是位于SELECTUPDATE、或DELETE语句中内部的查询

   

二、子查询的分类

    单行子查询

        返回零行或一行

    多行子查询

        返回一行或多行

    多列子查询

        返回多列

    相关子查询

        引用外部SQL语句中的一列或多列

    嵌套子查询

        位于其它子查询中的查询

 

三、子查询语法 */

    SELECT select_list

    FROM table

    WHERE expr operator

       (SELECT select_list

        FROM table);

        /*

    子查询(内部查询)在执行主查询之前执行一次

    然后主查询(外部查询)会使用该子查询的结果 

 

四、子查询的规则

    将子查询括在括号中

    将子查询放置在比较条件的右侧

    只有在执行排序Top-N分析时,子查询中才需要使用ORDER BY 子句

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

 

五、单行子查询

    仅返回一行

    使用单行的表较运算符:= ,>, >= ,< , <= ,<>

   

    WHERE 子句中使用子查询    */

    SQL> select ename,job from emp

      2  where empno = (

      3    select empno from emp

      4    where mgr = 7902 );

 

    ENAME      JOB

    ———- ———

    SMITH      CLERK

   

    使用分组函数的子查询

    SQL> select ename,job,sal

      2  from emp

      3  where sal >

      4    (select avg(sal) from emp);

 

    ENAME      JOB              SAL

    ———- ——— ———-

    JONES      MANAGER         2975

    BLAKE      MANAGER         2850

    CLARK      MANAGER         2450

    SCOTT      ANALYST         3000

    KING       PRESIDENT       5000

    FORD       ANALYST         3000

   

    HAVING子句中使用子查询

    SQL> select deptno,min(sal)

      2  from emp

      3  group by deptno

      4  having min(sal) >

      5      (select min(sal)

      6       from emp

      7       where deptno = 20);

 

       DEPTNO   MIN(SAL)

    ———- ———-

           30        950

           10       1300

          

    FROM 子句中使用子查询

    SQL> select empno,ename

      2  from

      3      (select empno,ename

      4       from emp

      5       where deptno = 20);

 

        EMPNO ENAME

    ———- ———-

         7369 SMITH

         7566 JONES

         7788 SCOTT

         7876 ADAMS

         7902 FORD

   

    单行子查询中的常见错误

        子查询的结果返回多于一行

       SQL> select empno,ename

         2  from emp

         3  where sal =

         4      (select sal     

         5       from emp

         6       where deptno = 20);

           (select sal

            *

       ERROR at line 4:

       ORA01427: singlerow subquery returns more than one row

      

       子查询中不能包含ORDER BY子句

       SQL> select empno,ename

         2  from emp

         3  where sal >

         4      (select avg(sal)

         5       from emp

         6       order by empno);

            order by empno)

            *

       ERROR at line 6:

       ORA00907: missing right parenthesis

      

       子查询内部没有返回行,如下语句可以正确执行,但没有数据返回

       SQL> select ename,job

         2  from emp

         3  where empno =

         4      (select empno

         5       from emp

         6       where mgr = 8000);

 

       no rows selected

 

    /* 

六、多行子查询

    返回多个行

    使用多行比较运算符IN ,ANY ,ALL

   

    在多行子查询中使用IN 操作符  */

    SQL> select empno,ename,job

      2  from emp

      3  where sal in

      4      (select max(sal)

      5       from emp

      6       group by deptno);

 

        EMPNO ENAME      JOB

    ———- ———- ———

         7698 BLAKE      MANAGER

         7902 FORD       ANALYST

         7788 SCOTT      ANALYST

         7839 KING       PRESIDENT

        

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

    SQL> select empno,ename,job

      2  from emp

      3  where sal < any

      4      (select avg(sal)

      5       from emp

      6       group by deptno);

 

        EMPNO ENAME      JOB

    ———- ———- ———

          7369 SMITH      CLERK

         7900 JAMES      CLERK

         7876 ADAMS      CLERK

         7521 WARD       SALESMAN

         7654 MARTIN     SALESMAN

         7934 MILLER     CLERK

         7844 TURNER     SALESMAN

         7499 ALLEN      SALESMAN

         7782 CLARK      MANAGER

         7698 BLAKE      MANAGER

        

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

    SQL> select empno,ename,job

      2  from emp

      3  where sal > all

      4      (select avg(sal)

      5       from emp

      6*      group by deptno)

   

        EMPNO ENAME      JOB

    ———- ———- ———

         7566 JONES      MANAGER

         7788 SCOTT      ANALYST

         7839 KING       PRESIDENT

         7902 FORD       ANALYST

   

     /*

七、相关子查询

    子查询中使用了主查询中的某些字段,主查询每扫描一行都要执行一次子查询 */

 

    查询工资高于同一部门的员工的部门号,姓名,工资

    SQL> select deptno,ename,sal

      2  from emp outer

      3  where sal >

      4      (select avg(sal)

      5       from emp inner

      6       where inner.deptno = outer.deptno);

 

       DEPTNO ENAME             SAL

    ———- ———- ———-

           30 ALLEN            1600

           20 JONES            2975

           30 BLAKE            2850

           20 SCOTT            3000

           10 KING             5000

           20 FORD             3000

          

    查询负责管理其它员工的员工记录(使用exists)

    SQL> select empno,ename

      2  from emp outer

      3  where exists

      4     (select empno

      5      from emp inner

      6      where inner.mgr = outer.empno);

 

        EMPNO ENAME

    ———- ———-

         7566 JONES

         7698 BLAKE

         7782 CLARK

         7788 SCOTT

         7839 KING

         7902 FORD

    查询不管理其它员工的职员(not exists)

    SQL> l3

      3* where exists

    SQL> c /where/where not

      3* where not exists

    SQL> l

      1  select empno,ename

      2  from emp outer

      3  where not exists

      4     (select empno

      5      from emp inner

      6*     where inner.mgr = outer.empno)

    SQL> /

 

        EMPNO ENAME

    ———- ———-

         7369 SMITH

         7499 ALLEN

         7521 WARD

         7654 MARTIN

         7844 TURNER

         7876 ADAMS

         7900 JAMES

         7934 MILLER

        

    EXISTS NOT EXISTS IN NOT IN 的比较

        EXISTSIN的不同:

            EXISTS只检查行的存在性,IN 要检查实际值的存在性(一般情况下EXISTS的性能高于IN)

        NOT EXISTS NOT IN

           当值列表中包含空值的情况下,NOT EXISTS 则返回true,NOT IN 则返回false.

          

    看下面的查询,查询部门号不在emp表中出现的部门名称及位置

    SQL> select deptno,dname,loc

      2  from dept d

      3  where not exists

      4      (select 1

      5       from emp e

      6*      where e.deptno = d.deptno)

     

       DEPTNO DNAME          LOC

    ———- ————– ————-

           40 OPERATIONS     BOSTON

      

    –IN与空值

           SQL> SELECT *

             2    FROM emp e

             3    WHERE e.empno NOT IN (

             4                           SELECT 7369 FROM dual

             5                           UNION ALL

             6                           SELECT NULL FROM dual

             7                          )

             8  ;

           

           EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO

           —– ———- ——— —– ———– ——— ——— ——

           

           SQL> SELECT *

             2    FROM emp e

             3    WHERE e.empno IN (‘7369’,NULL)

             4  ;

           

           EMPNO ENAME      JOB         MGR HIREDATE          SAL      COMM DEPTNO

           —– ———- ——— —– ———– ——— ——— ——

            7369 SMITH      CLERK      7902 19801217     800.00               20

           

    

    /* 

    注:子查询要包含在括号内

        子查询一般放在比较条件的右侧

        除非进行TOPN 分析,否则不要在子查询中使用ORDER BY */

 

    /*

八、多列子查询

    1、成对比较

    查询工资为部门最高的记录 */

    SQL> select * from scott.emp

      2  where (sal,job) in

      3     (select max(sal),job from scott.emp group by job);

   

        EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO

    ———- ———- ——— ———- ——— ———- ———- ———-

         7934 MILLER     CLERK           7782 23JAN82       1300                    10

         7499 ALLEN      SALESMAN        7698 20FEB81       1600        300         30

         7839 KING       PRESIDENT            17NOV81       5000                    10

         7566 JONES      MANAGER         7839 02APR81       2975                    20

         7902 FORD       ANALYST         7566 03DEC81       3000                    20

         7788 SCOTT      ANALYST         7566 19APR87       3000                    20   

      

       /*      

    2、非成对比较,实现了与上述类似的功能*/

    SQL> select * from scott.emp

      2  where sal in (select max(sal) from scott.emp group by job)

      3  and job in (select distinct job from scott.emp);

 

        EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO

    ———- ———- ——— ———- ——— ———- ———- ———-

         7934 MILLER     CLERK           7782 23JAN82       1300                    10

         7499 ALLEN      SALESMAN        7698 20FEB81       1600        300         30

         7566 JONES      MANAGER         7839 02APR81       2975                    20

         7788 SCOTT      ANALYST         7566 19APR87       3000                    20

         7902 FORD       ANALYST         7566 03DEC81       3000                    20

         7839 KING       PRESIDENT            17NOV81       5000                    10

        

     /*

九、嵌套子查询

    即位于子查询内部的子查询,嵌套层数最多可达层。然而应尽量避免使用嵌套子查询,使用表连接的查询性能会更高*/

    SQL> select deptno,Num_emp

      2  from (select deptno,count(empno) as Num_emp from emp group by deptno) d

      3  where Num_emp > 3;

 

       DEPTNO    NUM_EMP

    ———- ———-

           30          6

           20          5

      

    /*     

    注意:子查询对空值的处理

    除了count(*)外,都会忽略掉空值 */

 

    /*

十、更多*/  

Oracle 数据库实例启动关闭过程

 

Oracle 10g SGA 的自动化管理

 

使用OEM,SQL*Plus,iSQL*Plus 管理Oracle实例

 

Oracle实例和Oracle数据库(Oracle体系结构)

 

SQL 基础–>常用函数

 

SQL基础–>过滤和排序

 

SQL 基础–>SELECT 查询

 

 

 

   

 

 

   

 

  

    原文作者:ajuanabc
    原文地址: https://www.cnblogs.com/ajuanabc/archive/2010/05/14/2463459.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞