在偶然一次执行Oracle 9i的left outer join查询时,发现了一些匪夷所思的问题,在此贴出来和大家讨论一下。
先创建一些表和记录来模拟当时的情况:
create table temp_test1
(
a number(10)
);
INSERT INTO temp_test1 VALUES(1);
INSERT INTO temp_test1 VALUES(2);
INSERT INTO temp_test1 VALUES(3);
INSERT INTO temp_test1 VALUES(4);
COMMIT;
create table temp_test2
(
b number(10),
c varchar2(2)
);
INSERT INTO temp_test2 VALUES(1, 'a');
INSERT INTO temp_test2 VALUES(2, 'a');
INSERT INTO temp_test2 VALUES(3, 'a');
INSERT INTO temp_test2 VALUES(5, 'b');
COMMIT;
|
好了,我们来执行一个左外连接:
--最初想得到的结果
SELECT a, b, c
FROM temp_test1 LEFT OUTER JOIN temp_test2 ON temp_test1.a=temp_test2.b;
|
结果如下:
|
A
|
B
|
C
|
1
|
1
|
1
|
a
|
2
|
2
|
2
|
a
|
3
|
3
|
3
|
a
|
4
|
4
|
(预想的结果)
OK,在后面画蛇添足地加上个过滤条件:
--在temp_test2加一个条件(先连接,后过滤,结果少了一列)
SELECT a, b, c
FROM temp_test1 LEFT OUTER JOIN temp_test2 ON temp_test1.a=temp_test2.b
WHERE c='a';
|
结果居然少了一条:
|
A
|
B
|
C
|
1
|
1
|
1
|
a
|
2
|
2
|
2
|
a
|
3
|
3
|
3
|
a
|
(错误的结果)
从这个现象看,说明左外连接的时候,是先把两个表join起来,然后在合成后的结果集里面再做过滤。
再换种写法试试:
--在temp_test2加一个条件,换一种写法(似乎是过滤了再连接)
SELECT a, b, c
FROM temp_test1 LEFT OUTER JOIN temp_test2
ON temp_test1.a=temp_test2.b AND temp_test2.C='a';
|
神了,用这种方法居然是最初预想的结果。从这里看,似乎是在单表上过滤了再连接的。
不服气,把条件的顺序换了看:
SELECT a, b, c
FROM temp_test1 LEFT OUTER JOIN temp_test2
ON temp_test2.C='a' AND temp_test1.a=temp_test2.b;
|
还是我们预想的结果,看来条件的顺序和结果无关。
恩,越来越有趣了,再换写法,使用SQL89的连接语法:
--用另一种语法进行左连接
SELECT a,b,c
FROM temp_test1, temp_test2
WHERE temp_test1.a=temp_test2.b(+)
|
效果和left outer join果然是一样的!(废话)
加上画蛇添足的条件试试:
--用另一种语法进行左连接,加上过滤条件,发现是连接后再过滤
SELECT a,b,c
FROM temp_test1, temp_test2
WHERE temp_test1.a=temp_test2.b(+) AND temp_test2.C='a';
|
唉!错误的结果!再换条件的顺序:
--用另一种语法进行左连接,修改条件的顺序,发现还是连接后再过滤
SELECT a,b,c
FROM temp_test1, temp_test2
WHERE temp_test2.C='a' AND temp_test1.a=temp_test2.b(+);
|
还是错误的结果!
从上面的实验,我们得到了以下结论:
<!---->1、 <!---->对于SQL92语法的左外连接(left outer join),WHERE的过滤条件是连接后再过滤的;
<!---->2、 <!---->对于SQL92语法的左外连接(left outer join),把过滤条件写在FROM部分和写在WHERE部分效果是不同的;(为什么不同,到底有些什么不同不得而知,只能猜测)
<!---->3、 <!---->对于SQL89语法的左外连接( =(+) ),都是连接后再过滤的。
经过测试,RIGHT OUTER JOIN的表现与LEFT OUTER JOIN是一致的。
对于LEFT OUTER JOIN如此怪异的行为,我推荐一种比较“安全”的写法,强制在语法中体现我们的意图:
--强制性地过滤后再连接
WITH
result1 AS
(
SELECT b, c FROM temp_test2 WHERE c='a'
)
SELECT a,b,c
FROM temp_test1 LEFT OUTER JOIN result1 ON temp_test1.a=result1.b;
|
对于LEFT OUTER JOIN的怪异行为,还请高手指教。
分享到:
相关推荐
Oracle 9i Client (Oracle 9i 客户端) 简化版 (不安装Oracle客户端,也可以使用PLSQL Developer 不用安装Oracle客户端也可以使用PLSQL Developer 绿色! 安全! 轻便! 可靠! 1、本软件可作为简单的Oracle9i客户端...
在上面的源代码中,我们首先加载了ORACLE9I数据库的驱动程序,然后使用DriverManager.getConnection()方法连接到数据库。连接成功后,我们使用Statement对象执行SQL语句,最后使用ResultSet对象获取查询结果。 五、...
Oracle9i客户端精简版。 Oracle9i客户端精简版Oracle9i客户端精简版Oracle9i客户端精简版Oracle9i客户端精简版Oracle9i客户端精简版Oracle9i客户端精简版Oracle9i客户端精简版
本文将详细讲解如何安装Oracle 9i,以及如何连接到Oracle 9和10版本的数据库。 首先,Oracle 9i的安装过程可以分为以下几个步骤: 1. **系统需求检查**:确保你的操作系统支持Oracle 9i(例如Windows或各种Linux...
根据提供的标题、描述、标签及部分内容,我们可以整理出关于Oracle 9i的多个关键知识点,主要包括不同操作系统下的版本、下载链接以及如何获取这些资源的方法。 ### Oracle 9i概述 Oracle 9i 是甲骨文公司(Oracle ...
总的来说,Oracle 9i、10g、11g的ODBC驱动是连接Windows平台上应用程序与Oracle数据库的重要工具,它们不断适应Oracle数据库的新特性和性能优化,为开发者提供了灵活、高效的数据访问方式。正确配置和使用这些驱动,...
在“oracle9i310.msi”这个文件中,包含了Oracle 9i客户端的安装程序,用户只需运行此文件即可开始安装。 4. **使用说明.htm**:这个文件提供了关于如何使用客户端的指导,可能包括安装步骤、连接配置、基本操作等...
在本文档中,我们介绍了在 Windows Server 2003 上安装 Oracle9i 数据库的过程,包括安装 Windows Server 2003、安装 Oracle9i、使用 DBCA 创建数据库、配置监听及服务名、测试数据库连通等步骤。通过这些步骤,读者...
7. **安全性组件**:Oracle 9i提供了用户身份验证、权限管理和角色分配等安全特性,以保护数据库中的数据。 在安装"oracle9i310.msi"文件时,需要注意以下几点: - 确保计算机满足Oracle 9i的最低系统要求,包括...
在Oracle9i中,安装和配置是入门的第一步。教程可能会讲解如何在不同操作系统环境下安装数据库服务器和客户端工具,包括设置环境变量、创建监听器、配置网络服务名等。理解这些步骤对于后续的数据库管理和维护至关...
这个参考手册包含了关于Oracle 9i的全面信息,旨在帮助用户理解和操作该系统。Oracle 9i在设计时强调了性能优化、数据安全性、网络计算以及可扩展性,使其成为企业级数据库解决方案的首选。 首先,我们要了解Oracle...
在Oracle 9i中,EXP提供了不同的模式,如全库导出、用户模式导出、表模式导出等,以满足不同场景的需求。此外,用户还可以选择导出特定的表空间、数据块或者时间范围的数据。 **IMP(Import)**则是Oracle数据库的...
Oracle 9i是一款历史悠久的关系型数据库管理系统,由甲骨文公司(Oracle Corporation)开发,它在2001年发布,提供了许多先进的特性和功能,为企业的数据存储和管理提供了强大的支持。本压缩包“oracle9i客户端精简...
Oracle9i是Oracle公司推出的一款强大的关系数据库管理系统,它以其高效、稳定和灵活的特点在企业级应用中占据重要地位。本教程将深入探讨Oracle9i的核心概念和技术,帮助读者全面了解和掌握这个系统。 一、数据库...
在Oracle 9i中,创建数据库需要规划数据表结构,定义字段类型、长度和约束条件,如主键、外键、唯一性等。 安装Oracle 9i是一个复杂的过程,涉及服务器硬件需求、操作系统兼容性、网络配置等。初学者应了解安装前的...
Oracle 9i 物理结构是数据库管理系统的核心组成部分,它决定了数据如何在磁盘上存储、管理和访问。Oracle 9i 物理结构主要由以下几个关键组件构成: 1. **数据文件 (Data Files)**: 扩展名为 .DBF 的数据文件是...
在这个例子中,操作系统是SuSE Linux 7.2,已经安装了Oracle9i Enterprise Edition Release 9.0.1,且ORACLE SID(System Identifier)被设置为ora901。 使用Database Configuration Assistant (DBCA)来创建新的...
尽管本文旨在技术分享,揭示Oracle9i连接机制中可能存在的安全漏洞,但需强调的是,未经授权的数据库访问和信息截取行为严重违反了网络安全法规与道德规范。本文提供的信息仅用于合法的系统审计、安全研究或教育目的...
在Oracle 9I中,通过网络服务名配置和TNS(Transparent Network Substrate)协议,客户端可以直接连接到其他远程数据库,实现数据交互,简化了网络架构。 4. **SQL*Plus**:SQL*Plus是Oracle提供的一个命令行工具,...
在不同的Oracle版本中,默认的`block size`可能不同,例如,Oracle 9i默认的`block size`为8K或16K,而Oracle 11g默认的`block size`为8K。 #### 三、问题分析 在本案例中,源数据库为Oracle 9i,目标数据库为...