Oracle数据库之SQL连接查询

发表于:2013-05-31来源:Csdn作者:一个小菜仔点击数: 标签:oracle
前言 现实中有这么一种需求,有时候我们需要查询的数据是在多个表中的,那么如何从多个表中查询数据 呢?这就需要通过表的连接来实现查询了。

  前言

  现实中有这么一种需求,有时候我们需要查询的数据是在多个表中的,那么如何从多个表中查询数据

  呢?这就需要通过表的连接来实现查询了。

  笛卡尔积

  在定义连接之前我们需要简单的了解一下笛卡尔积,笔者不会纠结与其定义,只是看看其实际效果

  其实笛卡尔积就是没有连接条件或者连接条件无效的连接,例如:

  [sql] view plaincopyprint?

  select *from emp ,dept;--其结果倾向于一个巨大的记录数,无实际意义

  select *from emp ,dept;--其结果倾向于一个巨大的记录数,无实际意义

  上面可以看出笛卡尔积得出的是一个巨大的无意义的记录集合,我们可以通过在where子句中使用

  有效的连接来避免这种情况,使之具有实际意义。

  连接定义

  就是在笛卡尔积的基础上使用连接条件,例如根据两个表的相同列进行连接。若果要进行n个表的

  连接那么就的添加n-1个连接条件。例如:

  [sql] view plaincopyprint?

  select *from emp ,dept where emp.deptno = dept.deptno;

  select *from emp ,dept where emp.deptno = dept.deptno;

  连接类型

  连接主要有两种类型等值连接、非等值连接.

  还包括一些其他的连接方式:多连接、自连接、 定置运算符

  等值连接

  上面已经使用过了,即是表连接的where条件是一个表的列等于另一个表的列,通常情况下是主键和

  外键的判等连接。

  [sql] view plaincopyprint?

  select *from emp ,dept where emp.deptno = dept.deptno;

  select *from emp ,dept where emp.deptno = dept.deptno;

  Tips:因为deptno在两个表中都存在,所以要使用表.字段的形式,否则oracle认为其歧义

  等值连接中同样还可以添加约束条件

  [sql] view plaincopyprint?

  select *from emp ,dept where emp.deptno = dept.deptno and emp.ename ='CLARK';

  --结果只取一条记录

  select *from emp ,dept where emp.deptno = dept.deptno and emp.ename ='CLARK';

  --结果只取一条记录

  同样可以定义标的别名,不过需要注意的是定义了别名之后,必须通过别名访问字段,不能通过

  表明来访问了

  [sql] view plaincopyprint?

  select *from emp e ,dept d where e.deptno = d.deptno and e.ename ='CLARK';

  select *from emp e ,dept d where e.deptno = d.deptno and e.ename ='CLARK';

  非等值连接

  通过观察scott用户下的emp表和salgrade表,可以知道的是他们之间没有直接的对应项,而是

  emp的sal列的值在salgrade表中的LOSAL和HISAL之间,他们不是等值连接。

  [sql] view plaincopyprint?

  select * from emp e,salgrade s where e.sal between s.losal and s.hisal;

  select * from emp e,salgrade s where e.sal between s.losal and s.hisal;

  外连接

  使用外连接,返回连接两边有一边为NULL的记录,外连接的运算符是(+)

  外连接运算符可以在左边也可以在右边,但是不能同时在左边和右边,

  有(+)的一边表示这边的值要么等于另一边,要么为NULL

  例子:

  [sql] view plaincopyprint?

   select *from emp e ,dept d where e.deptno(+) = d.deptno ;

  --表明e.deptno可以为NULL

  

  select *from emp e ,dept d where e.deptno(+) = d.deptno ;

  --表明e.deptno可以为NULL

  同理,右边的情况是一样的,这里就不演示了

  右外连接

  以连接右边的表为基准对齐,不足内容补位空值

  [sql] view plaincopyprint?

  select *from emp e right outer join dept d on(e.deptno =d.deptno);

  select *from emp e right outer join dept d on(e.deptno =d.deptno);

  这种方式的产生的结果与下面的结果一样

  [sql] view plaincopyprint?

  select *from emp e ,dept d where e.deptno(+) = d.deptno ;

  select *from emp e ,dept d where e.deptno(+) = d.deptno ;

  左外连接

  以连接左边的表为基准对齐,不足内容补位空值

  [sql] view plaincopyprint?

  select *from emp e left outer join dept d on(e.deptno =d.deptno);

  select *from emp e,dept d where e.deptno = d.deptno(+);

  select *from emp e left outer join dept d on(e.deptno =d.deptno);

  select *from emp e,dept d where e.deptno = d.deptno(+);

  可以看出哪边补位,(+)就在哪边!

  全外连接

  通俗的讲:左边,右边都可以出现NULL(但是不可能同时出现)

  虽然(+)不能同时添加到两边,但是从9i之后可以使用下面的方式进行

  [sql] view plaincopyprint?

  select *from emp e full outer join dept d on(e.deptno =d.deptno);

  select *from emp e full outer join dept d on(e.deptno =d.deptno);

  这种方式查出来的记录相较于前面的一般会多一些

原文转自:http://blog.csdn.net/kiritor/article/details/8771280