ORACLE 8i,9i 表连接方法。

一般的相等连接:

select * from a, b where a.id = b.id;

这个就属于内连接。

对于外连接:

Oracle中可以使用“(+) ”来表示,9i可以使用LEFT/RIGHT/FULL OUTER JOIN

LEFT OUTER JOIN:左外关联

SELECT e.last_name, e.department_id, d.department_name

FROM employees e

LEFT OUTER JOIN departments d

ON (e.department_id = d.department_id);

等价于

SELECT e.last_name, e.department_id, d.department_name

FROM employees e, departments d

WHERE e.department_id=d.department_id(+)

结果为:所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录。

RIGHT OUTER JOIN:右外关联

SELECT e.last_name, e.department_id, d.department_name

FROM employees e

RIGHT OUTER JOIN departments d

ON (e.department_id = d.department_id);

等价于

SELECT e.last_name, e.department_id, d.department_name

FROM employees e, departments d

WHERE e.department_id(+)=d.department_id

结果为:所有员工及对应部门的记录,包括没有任何员工的部门记录。

FULL OUTER JOIN:全外关联

SELECT e.last_name, e.department_id, d.department_name

FROM employees e

FULL OUTER JOIN departments d

ON (e.department_id = d.department_id);

结果为:所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录和没有任何员工的部门记录。ORACLE8i是不直接支持完全外连接的语法,也就是说不能在左右两个表上同时加上(+),下面是在ORACLE8i可以参考的完全外连接语法

select t1.id,t2.id from table1 t1,table t2 where t1.id=t2.id(+)

union

select t1.id,t2.id from table1 t1,table t2 where t1.id(+)=t2.id

连接类型定义图示例子

内连接只连接匹配的行select A.c1,B.c2 from A join B on A.c3 = B.c3;

左外连接包含左边表的全部行(不管右边的表中是否存在与它们匹配的行)以及右边表中全部匹配的行select A.c1,B.c2 from A left join B on A.c3 = B.c3;

右外连接包含右边表的全部行(不管左边的表中是否存在与它们匹配的行)以及左边表中全部匹配的行select A.c1,B.c2 from A right join B on A.c3 = B.c3;

全外连接包含左、右两个表的全部行,不管在另一边的表中是否存在与它们匹配的行select A.c1,B.c2 from A full join B on A.c3 = B.c3;

(theta)连接使用等值以外的条件来匹配左、右两个表中的行select A.c1,B.c2 from A join B on A.c3 != B.c3;

交叉连接生成笛卡尔积——它不使用任何匹配或者选取条件,而是直接将一个数据源中的每个行与另一个数据源的每个行一一匹配select A.c1,B.c2 from A,B;

对于下面的使用到外连接的sql,

例一 select a.col1,a.col3 from a,b where a.col1=b.col2(+)

关于连接条件,经常出现的错误等价如下

1,a.col1=b.col2 or a.col is null

2,a.col1=b.col2 or a.col1 not in (select b.col2 from b) or a.col1 is null

(+)在右边,保证了左边表中的所有记录都会被取到,相当于一部分(part A)是select a.col1,b.col2,a.col3 from a,b where a.col1=b.col2取出的这部分记录;另一部分(part B)是a表中不满足上面条件剩下的所有记录(包括2种,一种是记录中a.col1为空,另一种是a.col1取了b.col2未出现过的值)都会在表里面显示,这部分select出来的所有与b表相关的字段均为空。所以左连接查询得到的记录条数应该与a表一致(记录数一致是我目前05.8.21的认识,需要思考确认)

正确的等价: part A:a.col1=b.col2 等价于 a.col1 in (select b.col2 from b where b.col2=a.col1)。这个看起来似乎很废话,是为了与下面做对比。

part B :等价于 a.col1 not in (select b.col2 from b where b.col2=a.col1)。这个与a.col1 not in (select b.col2 from b where b.id is not null )的区别在于a.col1为空的记录是否能够被取出。对于b.col2 is not null这个限制,是因为在not in 中的select子查询的结果也就是b.col2为null的记录存在,主查询将一条记录也查不出来。这点和in不同。

null,not in,in的一些试验:

select 1 from dual where null is null; return 1 record

select 1 from dual where null = null; return 0 record

select 1 from dual where null in null; return 0 record

select 2 from dual where 1 in (select 1 from dual union select null from dual); return 1 record

select 2 from dual where 1 not in (select 1 from dual union select null from dual); return 0 record

注意这里面的限制,例一中主查询仅仅选择与a表有关的字段,所以上述等价成立:select a.col1,a.col3 from a where a.col1=b.col2 or a.col1 not in (select b.col2 from b where b.col2=a.col1 and b.col2 is not null)。如果选择部分b表中子段,则from 后的表需要包括b表,将无法实现上面的等价。这样的查询当然可以实现,但如果不使用左连接,查询语句会复杂的多。所以左右连接是非常简洁有用的语法。(因为子查询中可以出现主查询中的表名和字段名作为条件,子查询的表和字段不能被主查询直接使用,这很容易理解)

最最需要搞清楚的还是null和无记录的区别。select null from dual,返回了一条记录,只是值是null;例子select 1 from dual where 1=2,返回0条记录。

下面的试验,他们分别应用于not in 的子查询中

select a.id,a.name from test_1 a where a.id not in (select null from dual) ; return 0 record.

select a.id,a.name from test_1 a where a.id not in (select 1 from dual where 1=2) ; return a表所有记录

select a.id,a.name from test_1 a where a.id in (select 1 from dual where 1=2) ; return 0 record.

另外注意

select a.id,a.name from test_1 a where a.id in (select null from dual);return 0 record.

因为这里符合上面提到的null in null的情况。

8.23补充

select 1 from dual where null like null; return 0 record.

只有null is null 是肯定成立的。所以在考虑一些允许为空的字段与参数的等值条件时,例如一个varchar2类型,通常做的是where col like nvl(:p_1,'%'),此时当参数p_1为空,col为空的记录自然不应该匹配,但当参数p_1和col都为空,此条件无法涵盖。所以应该修改为where col like nvl(:p_1,'%') or (col is null and :p_1 is null)

ps.发现对于一般的开发工作,在不考虑性能优化什么的时候,最最容易出现bug的就是关于一些边界条件的考虑。

[@more@]

oracle 连接图示,ORACLE 表连接方法相关推荐

  1. Oracle 优化器_表连接

    概述 在写SQL的时候,有时候涉及到的不仅只有一个表,这个时候,就需要表连接了.Oracle优化器处理SQL语句时,根据SQL语句,确定表的连接顺序(谁是驱动表,谁是被驱动表及 哪个表先和哪个表做链接 ...

  2. oracle中的多表连接

    2019独角兽企业重金招聘Python工程师标准>>> 简单连接: 简单连接仅仅是通过select子句和from子句来连接多个表,其查询结果是一个通过笛卡尔积所生成的表.在实际需求中 ...

  3. Oracle练习:用表连接实现查询平均工资最高的部门信息

    Oracle练习 利用表连接查询平均工资最高的部门信息 当查询结果数据来自于多两张表时,需要使用特定的连接条件将两张表的记录连接在一起,这种语法"表链接". 在做查询平均工资最高的 ...

  4. 【Oracle】三种表连接方式

    表连接的方式有三种分别是:排序合并连接(Sort Merge Join).嵌套循环连接(Nested Loops Join).哈希连接(Hash Join). 1. 排序合并连接(Sort Merge ...

  5. ORACLE中的多表连接查询

    这篇文章讲述了多表之间连接,包括内连接.外连接,如有错误或者不妥之处,还请各位大佬批评指正. 连表 SQL中操作多个表,以便可以查询到所需数据,其中包括内连接.外链接.等值连接.非等值连接.左连接.右 ...

  6. Oracle 快速速复制表的方法

    方法一 CREATE TABLE TABLE_NAME1 AS SELECT * FROM TABLE_NAME2; 条件 表TABLE_NAME1不需要预先创建. 适用场景:快速备份表. 方法二 I ...

  7. hive 内连接 左外连接 右外连接 满外连接 左半开连接 交叉连接 多表连接 隐式连接

    目录 hive outline hive 内连接 inner join hive 左外连接 left join hive 右外连接 right join hive 满外连接 full join hiv ...

  8. mysql连接代码_MySQL 表连接

    MySQL数据库表有4种连接方式: 左连接(左外连接) 右连接(右外连接) 等值连接(内连接) 全连接(全外连接) 以下,小编将依次简要介绍,希望能对初学的小伙伴们有所裨益. 首先先介绍下将要使用的两 ...

  9. mysql 三个表的外连接方式,MySQL表连接使用详解,内连接,外连接,交叉连接

    本章节向大家介绍如何使用 MySQL 的 JOIN 在两个或多个表中查询数据. 前提如下供后面学习所用: 查看学生表的全部记录SELECT * FROM STUDENT; 查看地址表的全部记录:SEL ...

最新文章

  1. 实用的人工智能 但数据 Python 速查表
  2. Java8 stream filter map
  3. 修身论文2000字_软考论文怎么写
  4. 成都优步uber司机第四组奖励政策
  5. ubuntu初识一(装机)
  6. Spring-ConfigurationClassPostProcessor类
  7. php限制上传类型,php 上传类型限制的简单示例
  8. 欢迎大家制作搜狗输入法flash皮肤。
  9. php 阿里云短信接口 demo最新
  10. http://wsj356428476.iteye.com/blog/1655032
  11. 玩转Excel系列-index+match查找函数用法
  12. 台式计算机显示器的分辨率,直观:计算机的一般屏幕分辨率是什么?
  13. pyttsx3 语音包安装、使用详解
  14. 【开发工具】 Photoshop CS6 安装与破解
  15. 密码管理神器-1Password,安全与否?
  16. (理财六)贷款用途的分类
  17. 不要去外包亲身经历告诉你 去外包的后果
  18. 信息量和信息熵的理解
  19. android关于高精度GPS模块
  20. 华为开源的深度学习框架 MindSpore

热门文章

  1. catv系统主要有哪三部分组成_有线电视系统,看完电力工程技术专家分析,顿时学会了,太经典...
  2. matlab 2018 ccs,Matlab2018a 与ccs7生成tms320F2812代码调试记录
  3. python写个验证码
  4. 转:Oracle数据库一致性读的原理(Consistent Read)
  5. JS—触摸事件、手势事件
  6. 最大公约数与最小公倍数问题
  7. matlab 画非线性曲线,matlab 非线性曲线拟合, nlinfit  lsqcurvefit  lsqnonlin
  8. matlab 流星雨,dijkstra算法及其matlab实现
  9. linux应用对I2C设备驱动4种读写方法
  10. Android查看CPU和GPU使用率