Oracle外连接中对非连接条件使用(+)需要注意的地方
1.先来说下Oracle外连接语句中对非链接条件使用(+)的作用问题
之前问过朋友,当时大脑处于短路状态,居然没想明白作用是啥。先看例子如下:
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename(+)!='KING';
使用scott账户登录,执行上面的sql语句,可以分析出此sql语句的意图是将部门表和员工表进行左外链,找出链接中员工名字不为‘KING’的记 录,在emp.ename后面加上(+)后,名字为空的记录也会列出来,即没有员工的部门也会列出来,如果不加(+),这样的记录就列不出来。
2.上面是使用oracle自己的外联结语法的sql语句,如果使用ANSIsql1992标准,即left join,那么情况会有所变化,(+)不能同时和ANSI标准的join一起使用,那么我想emp.ename后面的(+)应该变成 emp.ename is null,(可经过试验,发现根据ename字段的类型不同,结果有所不同,一下列出几个sql语句,供试验,待有执行环境后,整理之,本次只整理了varchar的情况)
--vacrchar类型
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename!='KING';
select * from dept left join emp on(dept.deptno=emp.deptno) where emp.ename!='KING';
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename(+)!='KING';
select * from dept left join emp on(dept.deptno=emp.deptno) where emp.ename!='KING' or emp.ename is null;
--number类型
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.empno!=7782;
select * from dept left join emp on(dept.deptno=emp.deptno) and emp.empno!=7782;
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.empno(+)!=7782;
select * from dept left join emp on(dept.deptno=emp.deptno) and emp.empno!=7782 or emp.empno is null;
--char类型又不一样
(以上用!='KING',用=‘KING’又将如何?)
----------------------------------------------------------------------------------------------
分析:
先列出两张表的数据
dept:
10 | ACCOUNTING | NEW YORK |
20 | RESEARCH | DALLAS |
30 | SALES | CHICAGO |
40 | OPERATIONS | BOSTON |
emp:
10 | 7782 | CLARK | MANAGER | 7839 | 1981-6-9 | 2450.00 | |
10 | 7839 | KING | PRESIDENT | 1981-11-17 | 5000.00 | ||
10 | 7934 | MILLER | CLERK | 7782 | 1982-1-23 | 1300.00 | |
20 | 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | |
20 | 7566 | JONES | MANAGER | 7839 | 1981-4-2 | 2975.00 | |
20 | 7788 | SCOTT | ANALYST | 7566 | 1987-4-19 | 3000.00 | |
20 | 7876 | ADAMS | CLERK | 7788 | 1987-5-23 | 1100.00 | |
20 | 7902 | FORD | ANALYST | 7566 | 1981-12-3 | 3000.00 | |
30 | 7499 | ALLEN | SALESMAN | 7698 | 1981-2-20 | 1600.00 | 300.00 |
30 | 7521 | WARD | SALESMAN | 7698 | 1981-2-22 | 1250.00 | 500.00 |
30 | 7654 | MARTIN | SALESMAN | 7698 | 1981-9-28 | 1250.00 | 1400.00 |
30 | 7698 | BLAKE | MANAGER | 7839 | 1981-5-1 | 2850.00 | |
30 | 7844 | TURNER | SALESMAN | 7698 | 1981-9-8 | 1500.00 | 0.00 |
30 | 7900 | JAMES | CLERK | 7698 | 1981-12-3 | 950.00 |
dept对emp做外连接后的结果是:
10 | ACCOUNTING | NEW YORK | 7782 | CLARK | MANAGER | 7839 | 1981-6-9 | 2450.00 | 10 | |
10 | ACCOUNTING | NEW YORK | 7839 | KING | PRESIDENT | 1981-11-17 | 5000.00 | 10 | ||
10 | ACCOUNTING | NEW YORK | 7934 | MILLER | CLERK | 7782 | 1982-1-23 | 1300.00 | 10 | |
20 | RESEARCH | DALLAS | 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | 20 | |
20 | RESEARCH | DALLAS | 7566 | JONES | MANAGER | 7839 | 1981-4-2 | 2975.00 | 20 | |
20 | RESEARCH | DALLAS | 7788 | SCOTT | ANALYST | 7566 | 1987-4-19 | 3000.00 | 20 | |
20 | RESEARCH | DALLAS | 7876 | ADAMS | CLERK | 7788 | 1987-5-23 | 1100.00 | 20 | |
20 | RESEARCH | DALLAS | 7902 | FORD | ANALYST | 7566 | 1981-12-3 | 3000.00 | 20 | |
30 | SALES | CHICAGO | 7499 | ALLEN | SALESMAN | 7698 | 1981-2-20 | 1600.00 | 300.00 | 30 |
30 | SALES | CHICAGO | 7521 | WARD | SALESMAN | 7698 | 1981-2-22 | 1250.00 | 500.00 | 30 |
30 | SALES | CHICAGO | 7654 | MARTIN | SALESMAN | 7698 | 1981-9-28 | 1250.00 | 1400.00 | 30 |
30 | SALES | CHICAGO | 7698 | BLAKE | MANAGER | 7839 | 1981-5-1 | 2850.00 | 30 | |
30 | SALES | CHICAGO | 7844 | TURNER | SALESMAN | 7698 | 1981-9-8 | 1500.00 | 0.00 | 30 |
30 | SALES | CHICAGO | 7900 | JAMES | CLERK | 7698 | 1981-12-3 | 950.00 | 30 | |
40 | OPERATIONS | BOSTON |
最后一行,编号为40的部门是外连接的效果,emp表对应的字段都为空
- 首先,对于!=号,varchar
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename!='KING';
这条sql语句,但是发现40这个部门并不在结果中,也就是说,最后一行中虽然emp的ename为空,符合!=‘KING’的条件,但却没有作为结果返 回,似乎oracle认为这条记录不存在,于是想要这条结果出来,那么必须在条件emp.ename!='KING'处加上一个(+)即
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.ename(+)!='KING',使得好像是外联结果产生的记录中对应于emp表的ename字段的值是任何一个不为‘KING’的字符串,这样这条记录便被算作是结果列了出来。
同样,使用ANSI语法的语句
select * from dept left join emp on(dept.deptno=emp.deptno) where emp.ename!='KING'
也没有达到效果,仍然将外联结产生的记录排除在外了,如果想要包含该条记录,就应该加上emp.ename is null,即
select * from dept left join emp on(dept.deptno=emp.deptno) where emp.ename!='KING' or emp.ename is null
- 其次,再来看=号的情况
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.job='ASSISTENT'
但是结果是没有任何记录,因为外联结结果中没有任何记录符合其员工职位为ASSITENT,如果要达到我们的要求,sql语句应该写为
select * from dept,emp where dept.deptno=emp.deptno(+) and emp.job(+)='ASSISTENT' ,
(+)的作用就好象是使oracle造出了这样的外联结记录,部门的员工中有一个的工作职位是ASSISTENT,但因为实际并没有这样的记录,所以这条记录的emp表的字段都是空。
我们可能希望ANSI格式的SQL语句也能达到这样的效果,你也许可能想到加上emp.job is null不久可以了么,但是那样只会列出外连接记录,即部门40的记录,部门10,20和30的记录都不会列出来.
所以需要做如下变通,通过左外连接一个子查询来实现:
select * from dept left join (select * from emp where ename='ASSISTENT') t on dept.deptno=t.deptno
- 注意:
因为左连接在没有其他任何条件的情况下,会将左边表中的所有记录都列出来,实验发现,当条件中只有关于左边表中的条件时,无论!=还是=的情况,不论加上(+)还是不加,效果都是一样的,都不会有多余记录列出。
相关推荐
其一、就业面广:全球前100强企业99家都在使用ORACLE相关技术,中国政府机构,大中型企事业单位都能有ORACLE技术的工程师岗位。 其二、技术层次深:如果期望进入IT服务或者产品公司(类似毕博、DELL、IBM等),...
##### 3.6.11 我可以在任意版本的Oracle中使用任意版本的预编译器么? 通常不建议这样做。为了兼容性和稳定性考虑,最好使用与Oracle数据库版本相匹配的预编译器版本。 ##### 3.6.12 1405错误(Fetch column values...
你可以编辑实体属性,定义数据类型,并注意实体的复数名(Plural name)会作为Oracle数据库中的表名。外键不在实体属性中直接表示,而是体现在实体间的关系中。 8. **定义唯一键** 在唯一键的定义中,除了主键外,...
除了上述几点之外,还有一些特定的操作符使用时需要注意的地方: - **<> 操作符**:不等于操作符不会利用索引,应尽量避免使用。例如,`A <> 0` 可以替换为 `A > 0 OR A 。 - **LIKE 操作符**:使用 LIKE 进行...
Oracle数据库系统中,Temp表空间是用于存储临时段的地方,主要在执行排序、连接和创建索引等操作时使用。当遇到"Oracle temp表空间不足"的问题时,这通常意味着数据库运行过程中产生的临时数据超过了现有Temp表空间...
### Oracle DBA 日常工作手册知识点...以上内容详尽地概括了Oracle DBA在日常工作中需要注意的关键点以及在面对问题时应采取的步骤。遵循这些指南不仅可以提高数据库管理的效率,还能有效地避免和解决可能出现的问题。
在解决安装Oracle 11g客户端过程中遇到的INS-30131错误时,需要仔细检查临时目录的访问权限,确认关键的Windows服务正在运行,并在必要时使用特殊的命令行参数来绕过系统的某些检查。在执行安装步骤时,确保在命令行...
Oracle 11g数据库转储文件(dump files)是数据库管理员和开发人员在进行故障排查、数据恢复或学习数据库结构...记住,正确使用和管理转储文件是数据库管理中的重要技能,它能帮助你更好地维护和优化你的Oracle数据库。
### Oracle Data Integrator (ODI) 概念、安装步骤及基本配置步骤 #### Oracle Data Integrator...通过遵循上述步骤和注意事项,可以确保成功地安装、配置和使用Oracle Data Integrator,从而高效地完成数据整合任务。
在本文中,我们将深入探讨Oracle 11g的基础知识,包括安装过程、数据库架构、启动与关闭数据库的方法,以及使用PLSQL Developer和TOAD等工具进行数据库管理和维护。 **一、安装 Oracle Database 11G 软件** 在安装...
需要注意的是,由于Windows XP已经不再提供官方支持,建议在较新的操作系统上部署Oracle数据库以获得更好的安全性和兼容性。此外,随着技术的发展,当前版本的Oracle数据库已经更新至更高的版本,如Oracle 19c等,...
当处理RPC样式的WSDL文件时,需要注意一些与文档样式的WSDL文件不同的地方,例如参数传递方式和返回值的结构可能会有所不同。 #### 前提条件 - 对BPEL、XPath、XML Schema、WSDL和其他相关Web服务标准有一定的了解...
### Linux_x64_for_Oracle11g64bit_安装步骤及图解 #### 第一部分:Linux系统要求及配置 ...在整个过程中需要注意的是,保持软件包的最新状态、满足硬件要求以及正确配置系统环境变量都是非常重要的。
除了上述技术外,还可以通过调整SQL语句本身来优化性能,例如避免全表扫描、使用适当的连接方式(如JOIN操作)、减少子查询等。 9. **数据库配置**: 通过调整数据库参数(如初始化参数文件init.ora中的设置),...
在这个场景中,我们讨论的是如何在一个JSP页面上根据特定条件动态地加载另一个JSP页面,这个新加载的页面通常会显示从数据库(例如Oracle)中检索到的数据。这通常涉及到前端技术如jQuery和Ajax,以及服务器端的处理...
Oracle 10g R2允许用户将AWR数据导出并导入到其他数据库中,这样就可以在一个集中的地方审查来自多个数据库的性能指标。 - **数据整合**:通过使用`DBMS_WORKLOAD_REPOSITORY`包中的`AWR_EXTRACT`、`AWR_LOAD`等...