日期:2014-05-16  浏览次数:20521 次

多表连接

***********************************************
 ORACLE的连接(非SQL99的连接)
***********************************************

一、多表连接的起因
1、关系数据库的设计范式
(1)第一范式(1NF):属性不可分。
(2)第二范式(2NF):非主属性完全依赖于码。
(3)第三范式(3NF):符合2NF,并且,消除传递依赖。
 还有另外三个范式我就不多说了!

2、下面是范化的一个例子:我们来设一个EMPLOYEES(雇员表),其中字段有:EMPLOYEE_ID,NAME,JOB_ID,DEPARTMENT_ID
EMPLOYEES这个表用于保存雇员的信息,而你想要删除其中的一个雇员,这时你就必须同时删除一个部门和职位。范式就是要解决这个问题,你可以将这个表化为三个表,一个用于存储雇员的信息(EMPLOYEES),一个用于存储每个雇员所在部门的信息(DEPARTMENTS),另一个用于存储雇员的职位信息(JOBS),这样对其中一个表做添加或删除操作就不会影响另一个表。

3、我们在查询信息的往往要显示比较全面的信息,比如就上面的例子,我要查雇员的所有信息(雇员号、姓名,部门名称,职位等),这些信息分布在这三个表中,这时候就要把EMPLOYEES、DEPARTMENTS、JOBS这几个表连接起来显示全面的雇员信息。下面我们来讲讲各种连接。


 

二、笛卡尔乘积(以HR用户做测试)
1、要想从多个表中取数据,命令非常简单。我们可以在SELECT命令的FROM后,加多个表名,就是告诉Oracle我要从多个表中取数据。
select * from employees,departments;
显示的结果的总行数等于EMPLOYEES表的总行数乘以DEPARTMENTS表的总行数,如下操作:
hr@OCM> select count(*) from employees;

  COUNT(*)
----------
       105

hr@OCM> select count(*) from departments;

  COUNT(*)
----------
        28

hr@OCM> select count(*) from employees,departments;

  COUNT(*)
----------
      2940

hr@OCM> select 105*28 from dual;

    105*28
----------
      2940

2、就是将EMPLOYEES表的每一行,和DEPARTMENTS表的每一行,组合到一起。这种连接方式,叫笛卡尔乘积。也就是EMPLOYEES表有105行,DEPARTMENTS表有28行。连接结果有105*28,一共2940行。这样的连接结果,没有什么意义。

 

三、等值连接
1、操作如下:
EMPLOYEES表和DEPARTMENTS表有一个共同的列,就是DEPARTMENT_ID。
hr@OCM> select EMPLOYEE_ID,FIRST_NAME,DEPARTMENT_NAME
  2          from EMPLOYEES e,DEPARTMENTS d
  3     where e.DEPARTMENT_ID=d.DEPARTMENT_ID;

EMPLOYEE_ID FIRST_NAME           DEPARTMENT_NAME
----------- -------------------- ------------------------------
        200 Jennifer             Administration
        201 Michael              Marketing
        202 Pat                  Marketing
        114 Den                  Purchasing
        119 Karen                Purchasing
        115 Alexander            Purchasin

hr@OCM> select EMPLOYEE_ID,FIRST_NAME,DEPARTMENT_ID,DEPARTMENT_NAME
  2         from EMPLOYEES e,DEPARTMENTS d
  3         where e.DEPARTMENT_ID=d.DEPARTMENT_ID;
select EMPLOYEE_ID,FIRST_NAME,DEPARTMENT_ID,DEPARTMENT_NAME
                              *
ERROR at line 1:
ORA-00918: column ambiguously defined

2、只对两个表中,某些列相等的行进行连接,就是等值连接。在连接条件中,列名前的表名,e.DEPARTMENT_ID=d.DEPARTMENT_ID,也就是e和d有时可以省略。但是,只有当列名不相同时,才可省略。

3、表别名的意义:我为EMPLOYEES表定义了别名e,也就是在表名后加空格,然后再输入的字符,就是表的别名。DEPARTMENTS的别名是d。然后,表名.DEPARTMENT_ID