Chinaunix首页 | 论坛 | 博客
  • 博客访问: 121627
  • 博文数量: 37
  • 博客积分: 2094
  • 博客等级: 大尉
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-14 08:39
文章分类
文章存档

2010年(37)

分类: Oracle

2010-05-16 09:51:12

在很多时候一个表的数据已经无法满足我们对查询和统计的要求,这个时候就需要从不同的表、视图中选择数据,那么我们就需要从多表中选择数据。
多表选择数据可以是两个表或者视图,也可以是两个以上的表或者视图。
从多表查询数据也被称为多表连接,连接时数据库中常用的查询数据的方法。
我们先来如下的sql语句:
SQL> select jocky.deptno,jocky.dname from dept jocky;
    DEPTNO DNAME
---------- --------------
        10 ACCOUNTING
        20 RESEARCH
        30 SALES
        40 OPERATIONS
这里的jocky是我自行设定的表别名,再来看看如下操作:
SQL> select ji.ename,ji.job,ji.sal from emp ji;
ENAME      JOB              SAL
---------- --------- ----------
SMITH      CLERK            800
ALLEN      SALESMAN        1600
WARD       SALESMAN        1250
JONES      MANAGER         2975
MARTIN     SALESMAN        1250
BLAKE      MANAGER         2850
那么如何进行表连接呢?
SQL> select jocky.deptno,jocky.dname,ji.ename,ji.job,ji.sal
  2  from dept jocky,emp ji;
    DEPTNO DNAME          ENAME      JOB              SAL
---------- -------------- ---------- --------- ----------
        10 ACCOUNTING     SMITH      CLERK            800
        10 ACCOUNTING     ALLEN      SALESMAN        1600
        10 ACCOUNTING     WARD       SALESMAN        1250
        10 ACCOUNTING     JONES      MANAGER         2975
        10 ACCOUNTING     MARTIN     SALESMAN        1250
        10 ACCOUNTING     BLAKE      MANAGER         2850
        10 ACCOUNTING     CLARK      MANAGER         2450
部分省略!
有效连接条件与笛卡尔积
当一个连接条件无效或被遗漏时,其结果是一个笛卡尔积,其中所有行的组合都被显示(如我上面的操作),也就是第一个表中的所有行链接到第二个表中的所有行。所以一个笛卡尔积会产生大量的行,其结果没什么实际意义,所以应该尽量使用where子句来限制一下输出。
SQL> select * from jocky;   SQL> select * from ji;
EMPLOYEE_ID NAME            NAME           SALARY
----------- ----------      ---------- ----------
          1 jocky           jocky           10000
          2 john            john             5800
          3 smith           smith            8900
          4 mike            mike             6666
          5 kyte            kyte             9000
SQL> select a.employee_id,a.name,b.salary
  2  from jocky a,ji b
  3  where a.name = b.name
  4  order by salary;
EMPLOYEE_ID NAME           SALARY
----------- ---------- ----------
          2 john             5800
          4 mike             6666
          3 smith            8900
          5 kyte             9000
          1 jocky           10000
连接的类型
oracle sql的连接类型有下面几种:
equjion等值连接
no-equjion非等值连接
outer join外连接
self join自连接
其中外连接又分为:左连接、右连接、全外连接。
表连接原则
当数据从多表中查询时要使用连接条件,一个表中的行按照对应列中的公值被连接到另一个表中的行(是不是有点绕口啊!即通常所说的主键和外键)。
为了连接n个表在一起,你最少需要n-1个连接条件。但是如果表中有一个连接主键,那就另当别论了!
等值连接
等值连接是使用最多的一种连接方式
连接条件是两个表中的某个列相等(就如我上面的操作),当然上面的操作也可以写成:
SQL> select employee_id,a.name,salary
  2  from jocky,ji
  3  where jocky.name = ji.name
  4  order by salary;
EMPLOYEE_ID NAME           SALARY
----------- ---------- ----------
          2 john             5800
          4 mike             6666
          3 smith            8900
          5 kyte             9000
          1 jocky           10000
除了order by还可以用and来作为附加条件。
等值连接中的列别名、表别名
如果连接的两个表(或者两个以上)表中有相同名字的列,那么此列表现形式为“表名.列名”
表别名最多可以有30个字符
如果在from子句中表别名被用于指定的表,那么在整个select语句中都要使用表别名。
表别名只对当前的select语句有效。
不能对不同的表适用相同的表别名,如果使用,则只对使用的第一个表起作用。
多于两个表的等值连接
前面提到连接n个表需要n-1个连接条件,先来看看下面三个表:
SQL> select * from jocky; SQL> select * from ji; SQL> select * from oracle;
EMPLOYEE_ID NAME         NAME           SALARY   NAME       SEX
----------- ----------   ---------- ----------   ---------- ----------
          1 jocky        jocky           10000   jocky      man
          2 smith        smith            8900   smith      man
          3 mike         mike             9000   mike       woman
          4 john         john             6500   john       woman
          5 jack         jack             7000   jack       man
连接操作:
SQL> select a.employee_id,a.name,b.salary,c.sex
  2  from jocky a,ji b,oracle c
  3  where a.name = b.name
  4  and b.name = c.name;
EMPLOYEE_ID NAME           SALARY SEX
----------- ---------- ---------- ----------
          1 jocky           10000 man
          2 smith            8900 man
          3 mike             9000 woman
          4 john             6500 woman
          5 jack             7000 man
非等值连接
连接条件不是两个表的某列(或者某些列)相等,就是非等值连接。
其用的并不多
现在假设有两个表,分别为a和b
非等值连接的条件是:a的salary列中的大小在b的min_salary和max_salary之间,命令:
select ......
from ......
where a.salary between b.min_salary and max_salary;
 
外连接
普通的表连接(包括上面演示的部分)被称为内连接,内连接的特点是如果一个行不满足连接条件,该行将不出现在查询结果中。
当使用外连接,不满足连接条件的行也会在输出结果中。先看下面两张表:
SQL> select * from jocky;  SQL> select * from ji;
EMPLOYEE_ID NAME           NAME           SALARY
----------- ----------     ---------- ----------
          1 jocky          jocky           10000
          2 mike           mike             8000
          3 smith          smith            2500
          4 blues          blues            5000
          5 john           john             6800
                           green            5500
如果使用上面的等值连接的话,那么green用户是不会显示出来的!如果我们非要使green那行显示出来,那么我们就需要用到外连接;外连接的符号式+。如:
SQL> select a.employee_id,a.name,b.salary
  2  from jocky a,ji b
  3  where a.name(+)=b.name;
EMPLOYEE_ID NAME           SALARY
----------- ---------- ----------
          1 jocky           10000
          2 mike             8000
          3 smith            2500
          4 blues            5000
          5 john             6800
                             5500
显示b表中不满足的行,如果想显示a表中不满足的行则改写成a.name = b.name(+);
但是不支持两边都(+)
全外连接
SQL> select a.employee_id,a.name,b.salary
  2  from jocky a full outer join ji b
  3  on (a.name = b.name);
EMPLOYEE_ID NAME           SALARY
----------- ---------- ----------
          1 jocky           10000
          2 mike             8000
          3 smith            2500
          4 blues            5000
          5 john             6800
                             5500
左外连接
SQL> select a.employee_id,a.name,b.salary
  2  from jocky a
  3  left outer join ji b
  4  on (a.name = b.name);
EMPLOYEE_ID NAME           SALARY
----------- ---------- ----------
          1 jocky           10000
          2 mike             8000
          3 smith            2500
          4 blues            5000
          5 john             6800
右外连接
SQL> select a.employee_id,a.name,b.salary
  2  from jocky a
  3  right outer join ji b
  4  on(a.name = b.name);
EMPLOYEE_ID NAME           SALARY
----------- ---------- ----------
          1 jocky           10000
          2 mike             8000
          3 smith            2500
          4 blues            5000
          5 john             6800
                             5500
自连接
自连接是一种使用很少的连接形式,可以是等值或非等值的连接!自连接示例:
SQL> select a.name || 'salary is' || b.salary
  2  from ji a,ji b
  3  where a.name = b.name;
A.NAME||'SALARYIS'||B.SALARY
-----------------------------------------------------------
jockysalary is10000
mikesalary is8000
smithsalary is2500
bluessalary is5000
johnsalary is6800
greensalary is5500
SQL1999连接语法介绍
SQL 1999标准,也简称SQL 99,是国际标准组织于1999年定义的SQL标准,目前所有大、中型数据库都支持它
交叉连接
其实就等同于笛卡尔积
命令:select a.name,b.salary from jocky a cross join ji b;
SQL> select a.name,b.salary from jocky a cross join ji b;
NAME           SALARY
---------- ----------
jocky           10000
jocky            8000
jocky            2500
jocky            5000
jocky            6800
jocky            5500
mike            10000
mike             8000
mike             2500
自然连接
SQL> select a.employee_id,b.salary from jocky a natural join ji b;
EMPLOYEE_ID     SALARY
----------- ----------
          1      10000
          2       8000
          3       2500
          4       5000
          5       6800
 
阅读(1483) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~