数据库基本功之复杂查询的子查询

news2024/9/28 15:25:18

子查询返回的值可以被外部查询使用,这样的复合查询等效与执行两个连续的查询.

 

 1. 单行单列子查询

(>,<,=,<>,>=,<=)内部SELECT子句只返回一行结果

 2.多行单列子查询

(all, any, in,not in)
all (>大于最大的,<小于最小的)

SQL> select ename, sal from emp where sal >all (2000,3000,4000);

ENAME                                 SAL
------------------------------ ----------
KING                                 5000

SQL> -- 查找高于所有部门的平均工资的员工(>比子查询中返回的列表中最大的大才行)
SQL> select ename, job, sal from emp where sal > all (select avg(sal) from emp group by deptno);

ENAME                          JOB                                SAL
------------------------------ --------------------------- ----------
JONES                          MANAGER                           2975
FORD                           ANALYST                           3000
SCOTT                          ANALYST                           3000
KING                           PRESIDENT                         5000

SQL> -- 子查询结果
SQL> select avg(sal) from emp group by deptno;

  AVG(SAL)
----------
1566.66667
2916.66667
      2175

SQL> 

3. 多行子查询中使用any

(>大于最小的,<小于最大的)
any的意思是:比子查询中返回的列表中最小的大就行

注意和all的区别,any强调的是只要有任意一个符合就行了,所以>any只要比最小的大就行了.

SQL> 
SQL> select ename, sal from emp where sal>any(2000,3000,4000);

ENAME                                 SAL
------------------------------ ----------
JONES                                2975
BLAKE                                2850
CLARK                                2450
SCOTT                                3000
FORD                                 3000
KING                                 5000

6 rows selected.

SQL> 

4. 多行子查询中使用in/not in

(逐个比较是否有匹配的值)

SQL> 
SQL> select ename,sal from emp where sal in (800, 3000, 4000);

ENAME                                 SAL
------------------------------ ----------
SMITH                                 800
SCOTT                                3000
FORD                                 3000

SQL> -- NOT运算操作符可以使用在IN操作上,但不能使用在ANY,ALL操作.
SQL> select ename, sal from emp where sal not in (800,3000,4000);

ENAME                                 SAL
------------------------------ ----------
ALLEN                                1600
WARD                                 1250
JONES                                2975
MARTIN                               1250
BLAKE                                2850
CLARK                                2450
TURNER                               1500
ADAMS                                1100
JAMES                                 950
MILLER                               1300
KING                                 5000

11 rows selected.

SQL> 

5. 多行多列的子查询返回多列结果

以SELECT主查询的WHERE子句中的多个列合并作为成对比较 条件.

SQL> 
SQL> create table emp1 as select * from emp;

Table created.

SQL>
SQL> -- SMITH是20部门的员工
SQL> update emp1 set sal=1600,comm=300 where ename='SMITH';

1 row updated.

SQL> -- CLARK是10部门的员工
SQL> update emp1 set sal=1500,comm=300 where ename='CLARK';

1 row updated.

SQL> select * from emp1;

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7369 SMITH                          CLERK                             7902 17-DEC-80             1600        300         20
      7499 ALLEN                          SALESMAN                          7698 20-FEB-81             1600        300         30
      7521 WARD                           SALESMAN                          7698 22-FEB-81             1250        500         30
      7566 JONES                          MANAGER                           7839 02-APR-81             2975                    20
      7654 MARTIN                         SALESMAN                          7698 28-SEP-81             1250       1400         30
      7698 BLAKE                          MANAGER                           7839 01-MAY-81             2850                    30
      7782 CLARK                          MANAGER                           7839 09-JUN-81             1500        300         10
      7788 SCOTT                          ANALYST                           7566 24-JAN-87             3000                    20
      7844 TURNER                         SALESMAN                          7698 08-SEP-81             1500          0         30
      7876 ADAMS                          CLERK                             7788 02-APR-87             1100                    20
      7900 JAMES                          CLERK                             7698 03-DEC-81              950                    30
      7902 FORD                           ANALYST                           7566 03-DEC-81             3000                    20
      7934 MILLER                         CLERK                             7782 23-JAN-82             1300                    10
      7839 KING                           PRESIDENT                         8000 17-NOV-81             5000          0         10

14 rows selected.

SQL> 

5.2 要求:查找表中是与30部门的员工工资和奖金相同的其他部门的员工.

 

(现在20部门的SIMTH与30部门的ALLEN 有相同的工资和奖金)
多列子查询特点是主查询每一行中的列都要与子查询返回列表中的相应列同时进行比较,只有各列完全匹配时才显示主查询中的该数据行.

分解一下:

5.3 第一步, 查询30号部门的工资和奖金的结果集

此例没有对comm的空值进行处理

SQL> 
SQL> select sal,comm from emp1 where deptno=30;

       SAL       COMM
---------- ----------
      1600        300
      1250        500
      1250       1400
      2850
      1500          0
       950

6 rows selected.

SQL> 

5.4 第二步,列出表中属于这个结果集的所有员工.

SQL> select * from emp1 where (sal,comm) in (select sal,comm from emp1 where deptno=30);

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7369 SMITH                          CLERK                             7902 17-DEC-80             1600        300         20
      7499 ALLEN                          SALESMAN                          7698 20-FEB-81             1600        300         30
      7521 WARD                           SALESMAN                          7698 22-FEB-81             1250        500         30
      7654 MARTIN                         SALESMAN                          7698 28-SEP-81             1250       1400         30
      7844 TURNER                         SALESMAN                          7698 08-SEP-81             1500          0         30

SQL> 


 5.5 第三步,去掉30号部门

就显示出了在emp1表中与30部门中任意一个员工的工资和奖金完全相同的,但该员工不是来自30部门的员工信息.

SQL> 
SQL> select * from emp1 where (sal,comm) in (select sal,comm from emp1 where deptno=30) and deptno <>30;

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7369 SMITH                          CLERK                             7902 17-DEC-80             1600        300         20

SQL> 


5.6 知识点:

1)成对比较是不能使用>any或>all等多行单列比较符的.
2)成对比较时的多列顺序和类型必须一一对应.

6. 与非成对比较(含布尔运算)的区别

SQL> select * from emp1
  2  where sal in (select sal from emp1 where deptno=30)
  3  and nvl(comm,0) in (select nvl(comm,0) from emp1 where deptno=30)
  4  and deptno<>30;

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7369 SMITH                          CLERK                             7902 17-DEC-80             1600        300         20
      7782 CLARK                          MANAGER                           7839 09-JUN-81             1500        300         10

SQL> 

两个子查询返回的值分别与主查询中的sal和comm列比较,如果员工的工资与30部门任意一个员工相同,同时,奖金也与30部门任意一个员工相同,那么得到了两个员工的信息.

可见,成对比较(使用where (列,列))比非成对比较(使用where 列 and 列) 更为严苛

7. 关于布尔运算符not

7.1 not 否定后面的比较符

where empno=7788                where NOT (empno=7788)
where ename LIKE ‘S%’            where ename NOT LIKE ‘S%’
where deptno IN (20,30)            where deptno NOT IN (20,30)
where sal BETWEEN 1500 AND 3000    where sal NOT BETWEEN 1500 AND 3000
where comm IS NULL                where comm IS NOT NULL
where EXISTS (select子查询)        where NOT EXISTS (select子查询)

7.2 not in 在子查询中的空值问题

"in"与"not in"遇到空值时情况不同,"not in"如果子查询的结果集中有空值,那么主查询得到的结果集也是空.

SQL> 
SQL> select * from emp;

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7369 SMITH                          CLERK                             7902 17-DEC-80              800                    20
      7499 ALLEN                          SALESMAN                          7698 20-FEB-81             1600        300         30
      7521 WARD                           SALESMAN                          7698 22-FEB-81             1250        500         30
      7566 JONES                          MANAGER                           7839 02-APR-81             2975                    20
      7654 MARTIN                         SALESMAN                          7698 28-SEP-81             1250       1400         30
      7698 BLAKE                          MANAGER                           7839 01-MAY-81             2850                    30
      7782 CLARK                          MANAGER                           7839 09-JUN-81             2450                    10
      7788 SCOTT                          ANALYST                           7566 24-JAN-87             3000                    20
      7844 TURNER                         SALESMAN                          7698 08-SEP-81             1500          0         30
      7876 ADAMS                          CLERK                             7788 02-APR-87             1100                    20
      7900 JAMES                          CLERK                             7698 03-DEC-81              950                    30
      7902 FORD                           ANALYST                           7566 03-DEC-81             3000                    20
      7934 MILLER                         CLERK                             7782 23-JAN-82             1300                    10
      7839 KING                           PRESIDENT                         8000 17-NOV-81             5000          0         10

14 rows selected.

SQL> -- 查询empno的值,在mgr里存在空值
SQL> select * from emp where empno not in (select nvl(mgr,0) from emp);

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7369 SMITH                          CLERK                             7902 17-DEC-80              800                    20
      7499 ALLEN                          SALESMAN                          7698 20-FEB-81             1600        300         30
      7521 WARD                           SALESMAN                          7698 22-FEB-81             1250        500         30
      7654 MARTIN                         SALESMAN                          7698 28-SEP-81             1250       1400         30
      7844 TURNER                         SALESMAN                          7698 08-SEP-81             1500          0         30
      7876 ADAMS                          CLERK                             7788 02-APR-87             1100                    20
      7900 JAMES                          CLERK                             7698 03-DEC-81              950                    30
      7934 MILLER                         CLERK                             7782 23-JAN-82             1300                    10

8 rows selected.

SQL> -- 查找出没有下属的员工,即普通员工,(该员工号不在mgr之列的)
SQL> select * from emp where empno not in (select mgr from emp);

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7369 SMITH                          CLERK                             7902 17-DEC-80              800                    20
      7499 ALLEN                          SALESMAN                          7698 20-FEB-81             1600        300         30
      7521 WARD                           SALESMAN                          7698 22-FEB-81             1250        500         30
      7654 MARTIN                         SALESMAN                          7698 28-SEP-81             1250       1400         30
      7844 TURNER                         SALESMAN                          7698 08-SEP-81             1500          0         30
      7876 ADAMS                          CLERK                             7788 02-APR-87             1100                    20
      7900 JAMES                          CLERK                             7698 03-DEC-81              950                    30
      7934 MILLER                         CLERK                             7782 23-JAN-82             1300                    10

8 rows selected.

SQL>

上面的结果不出所料,主查询没有返回记录.这个原因是在子查询中有一个空值,而对于not in这种形式,一旦子查询出现了空值,则主查询记录结果也就返回空了.

注意:not后不能跟单行比较符,只有not in组合,没有not any 和not all的组合,但 not后可以接表达式 如:
where empno not in(...)与where not empno in(...)两个写法都是同样结果,前者是not in组合,后者是not一个表达式.

SQL> -- 例:排除空值的影响
SQL> select ename from emp where empno not in (select nvl(mgr,0) from emp);

ENAME
------------------------------
SMITH
ALLEN
WARD
MARTIN
TURNER
ADAMS
JAMES
MILLER

8 rows selected.

SQL> 

8. from 中使用子查询(也叫内联视图)

例:员工的工资大于他所在的部门的平均工资的话,显示其信息.

分两步来考虑:
第一步,先看看每个部门的平均工资,再把这个结果集作为一个内联视图.

SQL> 
SQL> select deptno,avg(sal) salavg from emp group by deptno;

    DEPTNO     SALAVG
---------- ----------
        30 1566.66667
        10 2916.66667
        20       2175

SQL> 

第二步,把这个内联视图起一个别名b, 然后和emp 的别名e 做连接,满足条件即可.

SQL> 
SQL> select e.ename, e.sal, e.deptno, b.salavg
  2  from emp e, (select deptno, avg(sal) salavg from emp group by deptno) b
  3  where e.deptno = b.deptno
  4  and e.sal > b.salavg;

ENAME                                 SAL     DEPTNO     SALAVG
------------------------------ ---------- ---------- ----------
ALLEN                                1600         30 1566.66667
JONES                                2975         20       2175
BLAKE                                2850         30 1566.66667
SCOTT                                3000         20       2175
FORD                                 3000         20       2175
KING                                 5000         10 2916.66667

6 rows selected.

SQL> 

9.关联子查询与非关联子查询

从主查询(外部)调用子查询(内部)来看,可以有关联与非关联子查询之分

9.1 非关联子查询:

子查询部分可以独立执行,Oracle的in子查询一般用于非关联子查询 ,首先执行子查询,并将结果列表存放在加了索引的临时表中.即在执行子查询之前,系统先将主查询挂起,待子查询执行完毕,存放在临时表中以后再执行主查询.


SQL> -- 例:得到30号部门工资高于本部门平均工资的员工的信息
SQL> select ename,sal,deptno from emp where deptno=30 and sal > (select avg(sal) from emp where deptno=30);

ENAME                                 SAL     DEPTNO
------------------------------ ---------- ----------
ALLEN                                1600         30
BLAKE                                2850         30

SQL> 

9.2 关联子查询:

其子查询(内部,inner)会引用主查询(外部,outer)查询中的一列或多列.在执行时,外部查询的每一行都被一次一行地传递给子查询.
子查询依次读取外部查询传递来的每一值,并将其用到子查询上,直到外部查询所有的行都处理完为止.然后返回查询结果

9.2.1 实验准备

SQL> create table emp2 as (select e.empno, e.ename, d.loc, d.deptno from emp e, dept d where e.deptno = d.deptno(+));

Table created.

SQL> select * from emp2;

     EMPNO ENAME                          LOC                                         DEPTNO
---------- ------------------------------ --------------------------------------- ----------
      7782 CLARK                          NEW YORK                                        10
      7934 MILLER                         NEW YORK                                        10
      7839 KING                           NEW YORK                                        10
      7369 SMITH                          DALLAS                                          20
      7566 JONES                          DALLAS                                          20
      7788 SCOTT                          DALLAS                                          20
      7876 ADAMS                          DALLAS                                          20
      7902 FORD                           DALLAS                                          20
      7499 ALLEN                          CHICAGO                                         30
      7521 WARD                           CHICAGO                                         30
      7654 MARTIN                         CHICAGO                                         30
      7698 BLAKE                          CHICAGO                                         30
      7844 TURNER                         CHICAGO                                         30
      7900 JAMES                          CHICAGO                                         30

14 rows selected.

SQL> 

9.2.2 设置null

SQL> 
SQL> update emp2 set loc=null;

14 rows updated.

SQL> select * from emp2;

     EMPNO ENAME                          LOC                                         DEPTNO
---------- ------------------------------ --------------------------------------- ----------
      7782 CLARK                                                                          10
      7934 MILLER                                                                         10
      7839 KING                                                                           10
      7369 SMITH                                                                          20
      7566 JONES                                                                          20
      7788 SCOTT                                                                          20
      7876 ADAMS                                                                          20
      7902 FORD                                                                           20
      7499 ALLEN                                                                          30
      7521 WARD                                                                           30
      7654 MARTIN                                                                         30
      7698 BLAKE                                                                          30
      7844 TURNER                                                                         30
      7900 JAMES                                                                          30

14 rows selected.

SQL> commit;

Commit complete.

SQL> 

9.2.3 通过关联查询将emp2表更新回原值.

SQL> update emp2 e set loc = (select d.loc from dept d where e.deptno = d.deptno);

14 rows updated.

SQL> rollback;

Rollback complete.

SQL> 

9.3 关联查询中使用EXISTS和NOT EXISTS

EXISTS是在子查询里能否找到一个行值,如果子查询有行值,则立即停止子查询的搜索,然后返回逻辑标识TRUE, 如果子查询没有返回行值,则返回逻辑标识FALSE, 子查询要么返回T,要么返回F,以此决定了主查询的调用行的去留,然后主查询指针指向下一行,继续调用子查询..

9.3.1 EXISTS的例子

显示出emp表中那些员工不是普通员工(属于大小领导的).

SQL> -- 是否为领导
SQL> 
SQL> select empno,ename,job,deptno from emp outer where exists(select 'X' from emp where mgr=outer.empno);

     EMPNO ENAME                          JOB                             DEPTNO
---------- ------------------------------ --------------------------- ----------
      7566 JONES                          MANAGER                             20
      7698 BLAKE                          MANAGER                             30
      7782 CLARK                          MANAGER                             10
      7788 SCOTT                          ANALYST                             20
      7902 FORD                           ANALYST                             20
      7839 KING                           PRESIDENT                           10

6 rows selected.

SQL> 

说明:exists子查询中select 后的’X’只是一个占位,返回什么值无关紧要,它关心的是子查询中否’存在’,即子查询的where条件能否有’结果’.
一旦子查询一条记录满足where条件,则立即返回逻辑’TRUE’(就不往下查了).否则返回’FALSE’.

9.3.2 NOT EXISTS的例子

显示dept表中还没有员工的部门.

SQL> select deptno,dname from dept d where not exists (select 'X' from emp where deptno=d.deptno);

    DEPTNO DNAME
---------- ------------------------------------------
        40 OPERATIONS

SQL> 

对于关联子查询,在某种特定的条件下,比如子查询是个大表,且连接字段建立了索引,那么使用exists比in的效率可能更高.

10. 关于别名的使用

有表别名和列别名, 表别名用于多表连接或子查询中,列别名用于列的命名规范.
如果别名的字面值有特殊字符,需要使用双引号.如:"AB C"

10.1 必须使用别名的地方

10.1.1 两表连接后,select 投影中有相同命名的列,必须使用表别名区别标识

SQL> select ename, d. deptno from emp e, dept d where e. deptno=d. deptno;
-- 命名了别名.正确
SQL> create table emp1 as select deptno, avg(sal) salavg from emp group by deptno;
-- 表名无效
SQL> create table emp1 as select deptno, avg(sal) from emp group by deptno;
-- 或者
-- 表已创建
SQL> create table emp1(depno, abc) as select deptno, avg(sal) from emp group by deptno;
-- 命名了别名.正确
SQL> create view v as select deptno, avg(al) salavg from emp group by deptno;
-- 无效
SQL> create view v as select deptno, avg(sal) from emp group by deptno;

10.1.2 使用内联视图时, 若where子句还要引用select中函数的投影, 可使用别名.

SQL> 
SQL> select * from (select avg(sal) salavg from emp) where salavg > 2000;

    SALAVG
----------
2073.21429

SQL> 

10.1.3 内联视图作为多表连接,主查询投影列在形式上不允许单行字段(或函数)与聚合函数并列

解决这个问题是使在内联视图中为聚合函数加别名,然后主查询的投影中引用其别名.

SQL> 
SQL> select e.ename, e.sal, b.deptno,b.salavg from emp e, (select deptno, avg(sal) salavg from emp group by deptno) b where e.deptno = b.deptno;

ENAME                                 SAL     DEPTNO     SALAVG
------------------------------ ---------- ---------- ----------
SMITH                                 800         20       2175
ALLEN                                1600         30 1566.66667
WARD                                 1250         30 1566.66667
JONES                                2975         20       2175
MARTIN                               1250         30 1566.66667
BLAKE                                2850         30 1566.66667
CLARK                                2450         10 2916.66667
SCOTT                                3000         20       2175
TURNER                               1500         30 1566.66667
ADAMS                                1100         20       2175
JAMES                                 950         30 1566.66667
FORD                                 3000         20       2175
MILLER                               1300         10 2916.66667
KING                                 5000         10 2916.66667

14 rows selected.

SQL> 


10.1.4 rownum列是Oracle的伪列,加别名可以使它成为一个表列

这样才符合SQL99标准中的连接和选择.

SQL> 
SQL> select * from (select ename,rownum rn from emp) where rn > 5;

ENAME                                  RN
------------------------------ ----------
BLAKE                                   6
CLARK                                   7
SCOTT                                   8
TURNER                                  9
ADAMS                                  10
JAMES                                  11
FORD                                   12
MILLER                                 13
KING                                   14

9 rows selected.

SQL> 

10.2 不能使用别名的地方

10.2.1 在一个独立的select结构的投影中使用了列别名,不能在其后的where 或having中直接引用该列别名

原因: from  ——》where  ——》group by  ——》having  ——》order by  ——》select


SQL> select deptno,avg(sal) salavg from emp group by deptno having salavg > 2000;
select deptno,avg(sal) salavg from emp group by deptno having salavg > 2000
                                                              *
ERROR at line 1:
ORA-00904: "SALAVG": invalid identifier


SQL> select deptno,avg(sal) salavg from emp group by deptno having salavg>2000;
select deptno,avg(sal) salavg from emp group by deptno having salavg>2000
                                                              *
ERROR at line 1:
ORA-00904: "SALAVG": invalid identifier


SQL> 



from  ——》where  ——》group by  ——》having  ——》order by  ——》select

10.2. 别名不能出现在表达式里

-- 错
SQL> SELECT cust_name AS "NAME", cust_credit_limit/2 AS MIDPOINT,MIDPOINT+100 AS "MAX LOWER LIMIT" FROM customers;
-- 对
SQL> SELECT cust_name AS "NAME", cust_credit_limit/2 AS MIDPOINT,cust_credit_limit/2+100 AS "MAX LOWER LIMIT" FROM customers;

11. 简单查询与复杂查询练习题

11.1 列出emp表中工资最高的前三名员工信息

SQL> 
SQL> select * from emp order by sal desc;

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7839 KING                           PRESIDENT                         8000 17-NOV-81             5000          0         10
      7902 FORD                           ANALYST                           7566 03-DEC-81             3000                    20
      7788 SCOTT                          ANALYST                           7566 24-JAN-87             3000                    20
      7566 JONES                          MANAGER                           7839 02-APR-81             2975                    20
      7698 BLAKE                          MANAGER                           7839 01-MAY-81             2850                    30
      7782 CLARK                          MANAGER                           7839 09-JUN-81             2450                    10
      7499 ALLEN                          SALESMAN                          7698 20-FEB-81             1600        300         30
      7844 TURNER                         SALESMAN                          7698 08-SEP-81             1500          0         30
      7934 MILLER                         CLERK                             7782 23-JAN-82             1300                    10
      7521 WARD                           SALESMAN                          7698 22-FEB-81             1250        500         30
      7654 MARTIN                         SALESMAN                          7698 28-SEP-81             1250       1400         30
      7876 ADAMS                          CLERK                             7788 02-APR-87             1100                    20
      7900 JAMES                          CLERK                             7698 03-DEC-81              950                    30
      7369 SMITH                          CLERK                             7902 17-DEC-80              800                    20

14 rows selected.

SQL> select * from (select * from emp order by sal desc) where rownum < 4;

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7839 KING                           PRESIDENT                         8000 17-NOV-81             5000          0         10
      7788 SCOTT                          ANALYST                           7566 24-JAN-87             3000                    20
      7902 FORD                           ANALYST                           7566 03-DEC-81             3000                    20

SQL> 


-- 关于rownum 使用特别需要注意两点:
-- 1,rownum>时不会返回任何行,子查询后加别名方可.
-- 2,rownum<和and并用时,是在另一个条件基础上的rownum<  ,而不是两个独立的条件的并集(intersect)

-- 如:

SQL> 
SQL> select ename, sal, deptno from emp where deptno=10;

ENAME                                 SAL     DEPTNO
------------------------------ ---------- ----------
CLARK                                2450         10
MILLER                               1300         10
KING                                 5000         10

SQL> select ename,sal, deptno from emp where rownum <=1;

ENAME                                 SAL     DEPTNO
------------------------------ ---------- ----------
SMITH                                 800         20

SQL> select ename,sal, deptno from emp where rownum <=1 and deptno=10;

ENAME                                 SAL     DEPTNO
------------------------------ ---------- ----------
CLARK                                2450         10

SQL> 

11.2 列出emp表第5-第10名员工(按sal大--小排序)的信息(结果集的分页查询技术)

SQL> 
SQL> select * from emp order by sal desc;

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7839 KING                           PRESIDENT                         8000 17-NOV-81             5000          0         10
      7902 FORD                           ANALYST                           7566 03-DEC-81             3000                    20
      7788 SCOTT                          ANALYST                           7566 24-JAN-87             3000                    20
      7566 JONES                          MANAGER                           7839 02-APR-81             2975                    20
      7698 BLAKE                          MANAGER                           7839 01-MAY-81             2850                    30
      7782 CLARK                          MANAGER                           7839 09-JUN-81             2450                    10
      7499 ALLEN                          SALESMAN                          7698 20-FEB-81             1600        300         30
      7844 TURNER                         SALESMAN                          7698 08-SEP-81             1500          0         30
      7934 MILLER                         CLERK                             7782 23-JAN-82             1300                    10
      7521 WARD                           SALESMAN                          7698 22-FEB-81             1250        500         30
      7654 MARTIN                         SALESMAN                          7698 28-SEP-81             1250       1400         30
      7876 ADAMS                          CLERK                             7788 02-APR-87             1100                    20
      7900 JAMES                          CLERK                             7698 03-DEC-81              950                    30
      7369 SMITH                          CLERK                             7902 17-DEC-80              800                    20

14 rows selected.

SQL> select t1.*, rownum rn from (select * from emp order by sal desc) t1 
  2  ;

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO         RN
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ---------- ----------
      7839 KING                           PRESIDENT                         8000 17-NOV-81             5000          0         10          1
      7902 FORD                           ANALYST                           7566 03-DEC-81             3000                    20          2
      7788 SCOTT                          ANALYST                           7566 24-JAN-87             3000                    20          3
      7566 JONES                          MANAGER                           7839 02-APR-81             2975                    20          4
      7698 BLAKE                          MANAGER                           7839 01-MAY-81             2850                    30          5
      7782 CLARK                          MANAGER                           7839 09-JUN-81             2450                    10          6
      7499 ALLEN                          SALESMAN                          7698 20-FEB-81             1600        300         30          7
      7844 TURNER                         SALESMAN                          7698 08-SEP-81             1500          0         30          8
      7934 MILLER                         CLERK                             7782 23-JAN-82             1300                    10          9
      7521 WARD                           SALESMAN                          7698 22-FEB-81             1250        500         30         10
      7654 MARTIN                         SALESMAN                          7698 28-SEP-81             1250       1400         30         11
      7876 ADAMS                          CLERK                             7788 02-APR-87             1100                    20         12
      7900 JAMES                          CLERK                             7698 03-DEC-81              950                    30         13
      7369 SMITH                          CLERK                             7902 17-DEC-80              800                    20         14

14 rows selected.

SQL> select * from (select t1.*, rownum rn from (select * from emp order by sal desc) t1) where rn between 5 and 10;

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO         RN
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ---------- ----------
      7698 BLAKE                          MANAGER                           7839 01-MAY-81             2850                    30          5
      7782 CLARK                          MANAGER                           7839 09-JUN-81             2450                    10          6
      7499 ALLEN                          SALESMAN                          7698 20-FEB-81             1600        300         30          7
      7844 TURNER                         SALESMAN                          7698 08-SEP-81             1500          0         30          8
      7934 MILLER                         CLERK                             7782 23-JAN-82             1300                    10          9
      7521 WARD                           SALESMAN                          7698 22-FEB-81             1250        500         30         10

6 rows selected.

SQL> 

11.3 从列出emp表中显示员工和经理对应关系表.(emp自连接,利用笛卡尔积)

SQL> select a. empno, a. ename, a.mgr, b. empno, b. ename, b.mgr from emp a, emp b where a.mgr=b. empno;

     EMPNO ENAME                                 MGR      EMPNO ENAME                                 MGR
---------- ------------------------------ ---------- ---------- ------------------------------ ----------
      7788 SCOTT                                7566       7566 JONES                                7839
      7902 FORD                                 7566       7566 JONES                                7839
      7499 ALLEN                                7698       7698 BLAKE                                7839
      7521 WARD                                 7698       7698 BLAKE                                7839
      7654 MARTIN                               7698       7698 BLAKE                                7839
      7844 TURNER                               7698       7698 BLAKE                                7839
      7900 JAMES                                7698       7698 BLAKE                                7839
      7934 MILLER                               7782       7782 CLARK                                7839
      7876 ADAMS                                7788       7788 SCOTT                                7566
      7369 SMITH                                7902       7902 FORD                                 7566
      7566 JONES                                7839       7839 KING                                 8000
      7698 BLAKE                                7839       7839 KING                                 8000
      7782 CLARK                                7839       7839 KING                                 8000

13 rows selected.

SQL> 

11.4 要求列出emp表中最高工资的员工所在工作地点,(emp+dept左外)

SQL> select max(sal) from emp;

  MAX(SAL)
----------
      5000

SQL> select * from emp where sal = (select max(sal) from emp)
  2  ;

     EMPNO ENAME                          JOB                                MGR HIREDATE               SAL       COMM     DEPTNO
---------- ------------------------------ --------------------------- ---------- --------------- ---------- ---------- ----------
      7839 KING                           PRESIDENT                         8000 17-NOV-81             5000          0         10

SQL> select a.ename, d.loc from
  2  (select * from emp where sal = (select max(sal) from emp)) a
  3  left join dept d on a.deptno = d.deptno;

ENAME                          LOC
------------------------------ ---------------------------------------
KING                           NEW YORK

SQL> 

11.5 CTAS方法

建立dept1,在dept1表中增加一列person_count,要求根据emp表填写dept1表的各部门员工合计数(典型的关联查询).

SQL> 
SQL> create table dept2 as select * from dept;

Table created.

SQL> -- 表中增加一列
SQL> alter table dept2 add person_count int;

Table altered.

SQL> -- 关联查询扫描
SQL> update dept2 d set person_count= (select count (*) from emp e where e. deptno=d. deptno);

4 rows updated.

SQL> 
SQL> select * from dept2;

    DEPTNO DNAME                                      LOC                                     PERSON_COUNT
---------- ------------------------------------------ --------------------------------------- ------------
        10 ACCOUNTING                                 NEW YORK                                           3
        20 RESEARCH                                   DALLAS                                             5
        30 SALES                                      CHICAGO                                            6
        40 OPERATIONS                                 BOSTON                                             0

SQL> 

11.6 复杂select查询,

以HR用户的几个表为例,显示欧洲地区员工的平均工资及人数(使用多表连接及内联视图)

SQL> select avg(salary), count(salary)
  2  from
  3  (select e. first_name, e. salary, d. department_id, l. location_id, c. country_id, r. region_id, r. region_name 
  4  from employees e, departments d, locations l, countries c, regions r
  5  where e. department_id=d. department_id and d. location_id=l. location_id
  6  and l. country_id=c. country_id and c. region_id=r. region_id)
  7  where region_name='Europe';

AVG(SALARY) COUNT(SALARY)
----------- -------------
 8916.66667            36

SQL>

11.7 同上题(使用嵌套子查询技术)

select avg(salary), count (*)
from employees
where department_id in
	(select department_id
	from departments
	where location_id in
		(select location_id 
		from locations
		where country_id in
			(select country_id 
			from countries
			where region_id=
				(select region_id 
				from regions
				where region_name= 'Europe'
			)
		)
	)
);
AVG(SALARY)	COUNT(SALARY)
----------- -------------
8916.66667	36

-- 分解如下:

SQL> 
SQL> select region_id from regions where region_name = 'Europe';

 REGION_ID
----------
         1

SQL> select country_id from countries where region_id = 1;

COUNTR
------
BE
CH
DE
DK
FR
IT
NL
UK

8 rows selected.

SQL> select location_id from locations where country_id in('BE','CH','DE','DK','FR','IT','NL','UK');

LOCATION_ID
-----------
       2900
       3000
       2700
       1000
       1100
       3100
       2400
       2500
       2600

9 rows selected.

SQL> select department_id from departments where location_id in (1000,1100,2400,2500,2600,2700,2900,3000,3100);

DEPARTMENT_ID
-------------
           40
           80
           70

SQL> select avg(salary), count (*) from employees where department_id in (40,70,80);

AVG(SALARY)   COUNT(*)
----------- ----------
 8916.66667         36

SQL> 


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/399110.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux创建并挂载NAS

1 目标 在Linux服务器1上创建nas服务器&#xff0c;并指定可读写目录在Linux服务器2上挂载上述nas磁盘在Linux服务器2上设置开机自动挂载nas磁盘 2 搭建环境 两台Linux系统服务器&#xff0c;如下&#xff1a; 服务器1 IP为192.168.31.101 服务器2 IP为192.168.31.102 3 在服…

自动化测试——selenium多浏览器处理

这里写目录标题一、背景二、pytes hook函数1、conftest.py2、测试用例3、执行测试用例一、背景 用户使用的浏览器(frefox,chrome,IE 等) web应用应该能在任何浏览器上正常的工作&#xff0c;这样能吸引更多的用户来使用。 是跨不同浏览器组合验证网站或web应用程序功能的过程 …

Python高频面试题——生成器(最通俗的讲解)

生成器定义在 Python 中&#xff0c;使用了 yield 的函数被称为生成器&#xff08;generator&#xff09;。跟普通函数不同的是&#xff0c;生成器是一个返回迭代器的函数&#xff0c;只能用于迭代操作&#xff0c;更简单点理解生成器就是一个迭代器。 在调用生成器运行的过程中…

Ubuntu系统开机自动挂载NTFS硬盘【超实用】

由于跑深度学习实验(图像分割)f非常消耗内存&#xff0c;系统盘sda1内存小&#xff0c;配置了一个大容量得出NTFS机械盘&#xff0c;网上招了一些资料如何挂在&#xff0c;但是每次开机得手动挂载一遍才能使用硬盘&#xff0c;非常不方便&#xff0c;还容易造成数据丢失。 Step…

Elasticsearch使用系列-ES增删查改基本操作+ik分词

一、安装可视化工具KibanaES是一个NoSql数据库应用。和其他数据库一样&#xff0c;我们为了方便操作查看它&#xff0c;需要安装一个可视化工具 Kibana。官网&#xff1a;https://www.elastic.co/cn/downloads/kibana和前面安装ES一样&#xff0c;选中对应的环境下载&#xff0…

如何通过C++ 将数据写入 Excel 工作表

直观的界面、出色的计算功能和图表工具&#xff0c;使Excel成为了最流行的个人计算机数据处理软件。在独立的数据包含的信息量太少&#xff0c;而过多的数据又难以理清头绪时&#xff0c;制作成表格是数据管理的最有效手段之一。这样不仅可以方便整理数据&#xff0c;还可以方便…

【Python】tqdm 模块

import mathfrom tqdm import tqdm, trange# 计算阶乘 results_1 []for i in range(6666):results_1.append(math.factorial(i))这是一个循环计算阶乘的程序&#xff0c;我们不知道程序运行的具体情况&#xff0c;如果能加上一个程序运行过程的进度条&#xff0c;那可就太有趣…

REG.EXE修改注册表-解决win10微软输入法默认中文,将其全局修改为英文

REG.EXE修改注册表-解决win10微软输入法默认中文&#xff0c;将其全局修改为英文 使用REG.EXE 可以直接强制修改注册表字段 修改注册表&#xff1a; REG.EXE ADD 注册表路径 /v 注册表项字段 /t 注册表字段类型 /d 注册表值 /f 例如&#xff1a; REG. EX ADD HKLM\System\C…

Activiti7

文章目录Activiti官网一、BPM二、BPM软件三、BPMN四、Activiti使用步骤1、部署activiti2、流程定义3、流程定义部署4、启动一个流程实例5、用户查询待办任务(Task)6、用户办理任务7、流程结束五、Activiti环境准备1、下载扩展程序camunda-modeler2、配置idea扩展程序&#xff1…

[2.2.2]进程调度的时机、方式、切换与过程

文章目录第二章 进程管理进程调度的时机、方式、切换与过程&#xff08;一&#xff09;进程调度的时机&#xff08;二&#xff09;进程调度的方式&#xff08;三&#xff09;进程的切换与过程小结第二章 进程管理 进程调度的时机、方式、切换与过程 时机 什么时候需要进程调度…

在 KubeSphere 中开启新一代云原生数仓 Databend

作者&#xff1a;尚卓燃&#xff08;https://github.com/PsiACE&#xff09;&#xff0c;Databend 研发工程师&#xff0c;Apache OpenDAL (Incubating) PPMC。 前言 Databend 是一款完全面向云对象存储的新一代云原生数据仓库&#xff0c;专为弹性和高效设计&#xff0c;为您…

导入你的 ST 项目到 Visual Studio

去年我们官宣了 Visual Studio Code 可以直接导入 ST 项目&#xff0c;今天再次宣布&#xff1a;它的好兄弟 Visual Studio 2022 17.6 也支持此功能&#xff0c;详细请看下文。 在 ARM 微控制器领域&#xff0c;有许多芯片供应商&#xff0c;其中最大的是意法半导体(ST)。ST 拥…

【冲刺蓝桥杯的最后30天】day6

大家好&#x1f603;&#xff0c;我是想要慢慢变得优秀的向阳&#x1f31e;同学&#x1f468;‍&#x1f4bb;&#xff0c;断更了整整一年&#xff0c;又开始恢复CSDN更新&#xff0c;从今天开始更新备战蓝桥30天系列&#xff0c;一共30天&#xff0c;如果对你有帮助或者正在备…

【魅力开源】第9集:管理者的大局观:企业数字化转型的能力逆向规划设计模型

文章目录前言一、背景&#xff1a;数字化转型机遇与挑战1.1 国家层面&#xff1a;数字化转型的背后代表的是“国家意志”1.2 企业层面&#xff1a;积极拥抱数字化转型&#xff0c;抢占的是“红利先机”1.3 个人层面&#xff1a;全民数字化时代到来&#xff0c;最为炙手可热的当…

CPDA|如何证明你的数据分析能力?

数据分析能力是一个很重要的能力&#xff0c;那么如何去证明这个能力呢&#xff1f; 一般来说&#xff0c;证明你的数据分析能力需要以实际的数据分析项目和成果为基础&#xff0c;可以从以下几个方面来证明&#xff1a; 项目经历&#xff1a;列举你参与的数据分析项目&#x…

Easy Deep Learning——PyTorch中的自动微分

目录 什么是深度学习&#xff1f;它的实现原理是怎么样的呢&#xff1f; 什么是梯度下降&#xff1f;梯度下降是怎么计算出最优解的&#xff1f; 什么是导数&#xff1f;求导对于深度学习来说有何意义&#xff1f; PyTorch 自动微分&#xff08;自动求导&#xff09; 为什么…

分享一个 hive on spark 模式下使用 HikariCP 数据库连接池造成的资源泄露问题

最近在针对某系统进行性能优化时&#xff0c;发现了一个hive on spark 模式下使用 HikariCP 数据库连接池造成的资源泄露问题&#xff0c;该问题具有普适性&#xff0c;故特地拿出来跟大家分享下。 1 问题描述 在微服务中&#xff0c;我们普遍会使用各种数据库连接池技术以加快…

二叉树,二叉搜索树相关模板

目录1.先序遍历2.中序遍历3.后序遍历4.层序遍历(可用于需按层进行计算的题目)5.判定二叉树的对称性6.二叉树最大深度&#xff08;结点深度&#xff1a;根节点到该结点。结点高度&#xff1a;该结点到叶子结点&#xff09;7.二叉树最小深度8.二叉树的平衡性9.求左叶子的和10.通过…

ArcGIS制图技巧:制图入门与点、线、面状符号制作

目的&#xff1a; 1、了解地图制作目的&#xff1b; 2、了解在ArcMap平台中制作地图大致过程。 3、掌握地形图生成的操作&#xff1b; 4、掌握地形图的正确输出方法。 5、理解点状符号、线状符号、面状符号的基本概念&#xff1b; 6、理解地形点状符号、线状符号、面状符…

从大专到测开,上海某字母站大厂的面试题,岗位是测开(25K*16)

简单介绍一句&#xff0c;大专出身&#xff0c;三年经验。跳了四次槽&#xff0c;面试了无数次&#xff0c;现在把自己的面试经验整理出来分享给大家&#xff0c;堪称必杀技&#xff01; 1&#xff0c;一切从实际出发&#xff0c;对实际工作进行适当修饰 2&#xff0c;不会的简…