1 2 3 4

集合联合查询

集合

使用前提:两个集合必须有相同的列数,相同的列属性(数据类型,长度).

集合 关键字 五种运算 描述
并集 union all A union all B 取两个集合中所有的元素,不去除重复元素
union A union B 取两个集合中的所有元素,去掉重复元素
交集 intersect A intersect B 取两个集合重复部分的元素
差集合 minus A minus B A集合中的元素减去两个集合交叉部分的元素
B minus A B集合中的元素减去两个集合交叉部分的元素

union 显示两个集合的合集,并去掉重复部分,并按照从小到大自动排序;

SQL> select * from test1
  2  union
  3  select * from test2;

        ID NAME
---------- ------
         1 A
         2 B
         3 C
         4 D

union all 显示两个集合的合集,不去重

SQL> select * from test1
  2  union all
  3  select * from test2;

        ID NAME
---------- ------
         1 A
         2 B
         3 C
         1 A
         2 B
         4 D

minus:显示差集,显示第一个集合的数据去掉两个集合的合集部分

SQL> select * from test1
  2  minus
  3  select * from test2;

        ID NAME
---------- ------
         3 C
SQL> select * from test2
  2  minus
  3  select * from test1;

        ID NAME
---------- ------
         4 D

intersect:显示两个集合的交集

SQL> select * from test1
  2  intersect
  3  select * from test2;

        ID NAME
---------- ------
         1 A
         2 B

关联查询

定义: 当需要的数据在两张表或者多张表中时,需要用到关联查询

语法:关联查询使用到多张表时,from之后的表名用逗号隔开, where条件中必须有两个表关联的条件,实现关系传递.

准备数据

create table TEST1
(id number(5),
name varchar2(3)
);

insert into TEST1 values(1,'A');
insert into TEST1 values(2,'B');
insert into TEST1 values(3,'C');
commit;

create table TEST2 as select * from TEST1;

update TEST2 set ID=4, name='D' where id=3;
commit;
SQL> select * from test1;

        ID NAME
---------- ------
         1 A
         2 B
         3 C
SQL> select * from test2;

        ID NAME
---------- ------
         1 A
         2 B
         4 D

1内连接

根据条件将两张表的数据连接起来

如果没有符合条件的数据都会被过滤掉(会过滤掉两个表中的部分数据)

关键字:inner join
inner是可以省略的

SQL> select *
  2  from test1 t1 inner join test2 t2
  3  on t1.id=t2.id;

        ID NAME           ID NAME
---------- ------ ---------- ------
         1 A               1 A
         2 B               2 B

SQL> select *
  2  from test1 t1 join test2 t2
  3  on t1.id=t2.id;

        ID NAME           ID NAME
---------- ------ ---------- ------
         1 A               1 A
         2 B               2 B

也可以写为

SQL> select *
  2  from test1 t1,test2 t2
  3  where t1.id=t2.id;

        ID NAME           ID NAME
---------- ------ ---------- ------
         1 A               1 A
         2 B               2 B

查找员工编号为7521的人所在部门的全部信息

emp,dept

SQL> select * from dept a join emp b
  2  on a.deptno=b.deptno
  3  and b.empno=7521;

    DEPTNO DNAME                        LOC                             EMPNO ENAME                JOB                       MGR HIREDATE              SAL       COMM     DEPTNO
---------- ---------------------------- -------------------------- ---------- -------------------- ------------------ ---------- -------------- ---------- ---------- ----------
        30 SALES                        CHICAGO                          7521 WARD                 SALESMAN                 7698 22-2 月 -81           1250        500         30
SQL> select *
  2    from dept a, emp b
  3   where b.empno = 7521
  4     and a.deptno = b.deptno;

    DEPTNO DNAME                        LOC                             EMPNO ENAME                JOB                       MGR HIREDATE            SAL       COMM     DEPTNO
---------- ---------------------------- -------------------------- ---------- -------------------- ------------------ ---------- -------------- ---------- ---------- ----------
        30 SALES                        CHICAGO                          7521 WARD                 SALESMAN                 7698 22-2 月 -81        1250        500         30

2自连接

内连接的一种特殊形式,没有自己的关键字
一张表和它自己进来连接

查询员工姓名并查询员工的上级名称

SQL> select p1.ename,p2.ename
  2  from emp p1 join emp p2
  3  on p1.mgr=p2.empno;

ENAME                ENAME
-------------------- --------------------
FORD                 JONES
SCOTT                JONES
ALLEN                BLAKE
WARD                 BLAKE
JAMES                BLAKE

也可以写为

SQL> select p1.ename,p2.ename
  2  from emp p1,emp p2
  3  where p1.mgr=p2.empno;

ENAME                ENAME
-------------------- --------------------
FORD                 JONES
SCOTT                JONES
ALLEN                BLAKE
WARD                 BLAKE
JAMES                BLAKE

3不等连接

连接条件是不等关系的连接

查询员工编号,姓名 并显示员工的工资等级

SQL> select * from salgrade;

     GRADE      LOSAL      HISAL
---------- ---------- ----------
         1        700       1200
         2       1201       1400
         3       1401       2000
         4       2001       3000
         5       3001       9999
SQL> select p1.empno,p1.ename,s1.grade
  2  from emp p1 join salgrade s1
  3  on p1.sal between s1.losal and s1.hisal;

     EMPNO ENAME                     GRADE
---------- -------------------- ----------
      7369 SMITH                         1
      7900 JAMES                         1
      7876 ADAMS                         1
      7521 WARD                          2
      7654 MARTIN                        2
      7934 MILLER                        2
      7844 TURNER                        3
      7499 ALLEN                         3
      7782 CLARK                         4
      7698 BLAKE                         4
      7566 JONES                         4
      7902 FORD                          4
      7788 SCOTT                         4
      7839 KING                          5

查询比每个人工资低的人数

SQL> select p1.empno, p1.ename, p1.sal, count(*)
  2  from emp p1 join emp p2
  3  on p1.sal > p2.sal
  4  group by p1.empno, p1.ename, p1.sal;

     EMPNO ENAME                       SAL   COUNT(*)
---------- -------------------- ---------- ----------
      7566 JONES                      2975         10
      7698 BLAKE                      2850          9
      7521 WARD                       1250          3
      7654 MARTIN                     1250          3
      7876 ADAMS                      1100          2
      7782 CLARK                      2450          8
      7788 SCOTT                      3000         11
      7839 KING                       5000         13

查看比员工: ALLEN工资低的员工信息

SQL> select p1.empno, p1.ename, p1.sal,
  2         p2.empno, p2.ename, p2.sal
  3  from emp p1 join emp p2
  4  on p1.sal>p2.sal
  5  where p1.ename='ALLEN';

     EMPNO ENAME            SAL      EMPNO ENAME             SAL
---------- ----------- ---------- ---------- ----------------- ----------
      7499 ALLEN           1600       7369 SMITH             800
      7499 ALLEN           1600       7521 WARD             1250
      7499 ALLEN           1600       7654 MARTIN           1250
      7499 ALLEN           1600       7844 TURNER           1500
      7499 ALLEN           1600       7876 ADAMS            1100
      7499 ALLEN           1600       7900 JAMES             950
      7499 ALLEN           1600       7934 MILLER           1300

1全(外)连接

关键字:full outer join
outer:可以省略

  • 会查出两张表的所有数据

  • 根据关系列进行等值连接

  • 如果一张表中的数据,根据连接条件在另一张表中找不到相应的数据时,他会在相应的位置显示为空

SQL> select t1.*,t2.*
  2  from test1 t1 full join test2 t2
  3  on t1.id=t2.id;

        ID NAME           ID NAME
---------- ------ ---------- ------
         1 A               1 A
         2 B               2 B
                           4 D
         3 C

2左(外)连接

关键字:left outer join
outer:可以省略

  • 左连接是把左表的所有数据查询出来

  • 会根据连接条件去右表中找和它对应的数据

  • 如果找到就连接为一条数据,如果找不到就只显示左表的数据.右表部分显示为空(左连接会过滤掉右表中的部分数据)

SQL> select t1.*,t2.*
  2  from test1 t1 left join test2 t2
  3  on t1.id=t2.id;

        ID NAME           ID NAME
---------- ------ ---------- ------
         1 A               1 A
         2 B               2 B
         3 C

左连接的又一写法

SQL> select t1.*,t2.*
  2  from test1 t1,test2 t2
  3  where t1.id=t2.id(+);

        ID NAME           ID NAME
---------- ------ ---------- ------
         1 A               1 A
         2 B               2 B
         3 C

3右(外)连接

  • 右连接会查出所有右表的数据,根据连接条件去左表找对应的数据,如果找到就连接起来

  • 如果找不到,就显示为空

  • 右连接会过滤掉部分左表的数据

SQL> select t1.*,t2.*
  2  from test1 t1 right join test2 t2
  3  on t1.id=t2.id;

        ID NAME           ID NAME
---------- ------ ---------- ------
         1 A               1 A
         2 B               2 B
                           4 D

右连接的又一写法

SQL> select t1.*,t2.*
  2  from test1 t1,test2 t2
  3  where t1.id(+)=t2.id;

        ID NAME           ID NAME
---------- ------ ---------- ------
         1 A               1 A
         2 B               2 B
                           4 D

自然连接和交叉连接

1自然连接

关键字natural join

  • 自然连接会从两张表中找到列名相同的列进行等值连接

  • 如果在两张表中找不到关系列值相等的数据,这样的数据会被过滤掉

SQL> select *
  2  from test1 t1 natural join test2 t2;

        ID NAME
---------- ------
         1 A
         2 B

2交叉连接

关键字:cross join

拿表1中的一条数据和表2的所有数据依次进行连接
然后再拿表1第二条数据和表2的所有数据依次进行连接
以此类推排查出所有结果
交叉连接的结果条数,是第一张表的数据条数,乘以第二张表的数据条数

SQL> select *
  2  from test1 t1 cross join test2 t2;

        ID NAME           ID NAME
---------- ------ ---------- ------
         1 A               1 A
         1 A               2 B
         1 A               4 D
         2 B               1 A
         2 B               2 B
         2 B               4 D
         3 C               1 A
         3 C               2 B
         3 C               4 D

交叉连接又一写法

SQL> select *
  2  from test1 t1,test2 t2;

        ID NAME           ID NAME
---------- ------ ---------- ------
         1 A               1 A
         1 A               2 B
         1 A               4 D
         2 B               1 A
         2 B               2 B
         2 B               4 D
         3 C               1 A
         3 C               2 B
         3 C               4 D

补充all和any

后面跟一个集合或者子查询
all,any不能直接用等号,只能用<= | >=

选项 描述
>all 表示大于集合中最大的元素
<all 表示小于集合中最小的元素
>any 表示大于集合中最小的元素
<any 表示小于集合中最大的元素

查询员工信息要求,要求比下列工资都少(2000,1500,3000)

比列表中最少的还少

select * from emp where sal<all(2000,1500,3000);
posted @ 2019-10-31 19:53  多走多看  阅读(672)  评论(0编辑  收藏  举报