文档库 最新最全的文档下载
当前位置:文档库 › ORACLE 多表连接与子查询

ORACLE 多表连接与子查询

ORACLE 多表连接与子查询

Oracle表连接

SQL/Oracle使用表连接从多个表中查询数据

语法格式:

select字段列表

from table1,table2

where table1.column1=table2.column2;

说明:

在where子句中指定连接条件

当被连接的多个表中存在同名字段时,必须在该字段前加上"表名"作为前缀.连接的类型

Oracle8i之前的表连接:

等值连接(Equijoin)

非等值连接(Non-Equijoin)

外连接(Outer join):-->左外连接-->右外连接

自连接(Self join)

Oracle9之后新引入的连接形式(支持SQL99规范)

交叉连接(Cross join)

自然连接(Natural join)

使用Using子句建立连接

使用on子句建立连接

外连接(Outer join):-->左外连接-->右外连接-->全外连接

等值连接(Equijoin)

select empno,ename,sal,emp.deptno,dname from emp,dept

where emp.deptno = dept.deptno;

多表连接中:

?可使用AND操作符增加查询条件

?使用表别名可以简化查询

?使用表名(表别名)前缀可提高查询效率

?为了连接n个表,至少需要n-1个连接条件

非等值连接(Non-Equijoin)

外连接(Outer join)

使用外连接可以看到参与连接的某一方不满足连接条件的记录外连接运算符为(+)

传统的外连接分为左外连接和右外连接两种

语法格式:

select字段列表

from table1,table2

where table1.column1(+)=table2.column2;

select字段列表

from table1,table2

where table1.column1=table2.column2(+);

自连接(Self join)

select a.enpno,a.ename,a.ngr,b.ename

from emp a,emp b

where a.ngr = b.enpno;

SQL99连接语法

SQL1999规范中规定的连接查询语法

select字段列表

from table1

[cross join table2]|

[natural join table2]|

[join table2 using(字段名)]|

[join table2 on(table.column_name=table2.column_name)]|

[(left | right | full out ) join table2

on(table1.column_name=table2.column_name)];

交叉连接(Cross join)

Cross join 产生了一个笛卡尔集,其效果等同于再两个表进行连接时未使用where子句限定连接条件;

select empno,ename,sal,emp.deptno,dname

from emp cross join dept;

自然连接(Natural join)

Natural join基于两个表中的全部同名列建立连接

?从两个表中选出同名列的值均对应相等的所有行

?如果两个表中的同名列的所有数据类型不同,则出错

?不允许在参照列上使用表名或者别名作为前缀

select empno,ename,sal,emp.deptno,dname

from emp natural join dept;

Using子句

如果不希望参照被连接表的所有同名列进行等值连接,自然连接将无法满足要求,可以在连接时使用USING子句来设置用于等值连接的列(参照列)名.

select empno,ename,sal,emp.deptno,dname

from emp join dept

using(deptno);

不允许在参照列上使用表名或者别名作为前缀

On子句

如果要参照非同名的列进行等值连接,或想设置任意的连接条件,可以使用On子句

select empno,ename,sal,emp.deptno,dname

from emp join dept

on(emp.deptno=dept.deptno);

多表连接

使用SQL99连接语法,两个以上的表进行连接时应依次/分别指定相临的两个表之间的连接条件.

select字段列表

from table1

[cross join table2]|

[natural join table2]|

[join table2 using(字段名)]|

[join table2 on(table.column_name=table2.column_name)]|

[(left | right | full out ) join table2

on(table1.column_name=table2.column_name)]

[cross join table3]|

[natural join table3]|

[join table3 using(字段名)]|

[join table3 on(table.column_name=table3.column_name)]|

[(left | right | full out ) join table3

on(table2.column_name=table3.column_name)]...;

内连接和外连接

内连接(Inner join)

在SQL99规范中,内连接只返回满足连接条件的数据.

外连接(Outer join)

左外连接(Left Outer Join)

两个表在连接过程中除返回满足连接条件的行为外,还返回左表中不满足条件的行为,这种连接称为左外连接.

右外连接(Right Outer Join)

两个表在连接过程中除返回满足连接条件的行为外,还返回右表中不满足条件的行为,这种连接称为右外连接.

满外连接(Full Outer Join)

Oracle9开始新增功能,两个表在连接过程中除返回满足连接条件的行为外,还返回两个表中不满足条件的所有行为,这种连接称为满外连接.

子查询(Sub Query)

子查询子查询在主查询前执行一次

主查询使用子查询的结果

select字段列表

from table

where表达式 operator (select字段列表from table);

使用子查询注意事项

?在查询时基于未知时应考虑使用子查询

?子查询必须包含在括号内

?将子查询放在比较运算符的右侧,以增强可读性.

?除非进行Top-N分析,否则不要再子查询中使用Order by子句

?对单行子查询使用单行运算符

?对多行子查询使用多行运算符

单行子查询

单行子查询只返回一行记录

对单行子查询可使用单行记录比较运算符

=--------------等于

>--------------大于

>=------------大于等于

<--------------小于

<=--------------小于等于

<>--------------不等于

select*from emp

where sal>(select sal from emp where empno=7000);

子查询空值/多值问题

?如果子查询未返回任何行,则主查询页不会返回任何结果

?如果子查询返回单行结果,则为单行子查询,可以在主查询中对其使用相应的单行记录比较运算符

?如果子查询返回多行结果,则为多行子查询,此时不允许对其使用单行记录比较运算符

多行子查询

多行子查询返回多行记录

对多行子查询只能使用多行记录比较运算符

in--------------等于列表中的任何一个

any--------------和子查询返回的任意一个值比较

all--------------和子查询返回的所有值比较

select*from emp

where sal>any(select avg(sal) from emp group by deptno);

select*from emp

where sal>all(select avg(sal) from emp group by deptno);

select*from emp

where job in(select job from emp where ename='martin'or ename='ssss'); TopN查询

在oracle中通常采用子查询的方式来实现Top n查询

select字段列表

from(select字段列表from table order by排序字段)

where rownum <=n;

------------------------------------------------------------

select*

from(select*from emp order by sal desc)

where rownum <=5;

ORACLE表连接方式的分析与优化-tony

数据仓库环境ORACLE 表连接方式的分析与优化a 摘要:针对在数据仓库环境下,由于超大数据量的处理而产生的效率问题,本文深入分析了ORACLE表的几种连接方式、特点、适用范围,以及对于如何使用和优化做了详细的探讨。 关键字:数据仓库 ORACLE 表连接 一引言 数据仓库技术是目前已知的比较成熟和被广泛采用的解决方案,用于整和电信运营企业内部所有分散的原始业务数据,并通过便捷有效的数据访问手段,可以支持企业内部不同部门,不同需求,不同层次的用户随时获得自己所需的信息。数据仓库系统需要能够及时地追踪和分析大量的历史数据,并能够及时做出分析和预测,因此实时性是一个非常重要的指标。ORACLE由于可靠性、高性能等方面的特点,在电信行业大部分的数据仓库系统中担当了后台数据库的角色。由于电信行业的特点,处理的数据量十分庞大,处理的时间长。尤其是对于大表之间的关联操作,有的大表的记录数达到数亿条,处理时间更是漫长,这成为影响数据库运行效率的主要因素。因此,对于数据库的性能优化相当重要。性能优化是个很大的课题,需要综合考虑,从服务器、磁盘、网络、ORACLE实例、ORACLE SQL等多方面着手。本文着重分析ORACLE SQL优化中对于系统性能影响极大的表连接方式、特点、适用范围,并对如何使用和优化做了详细的探讨。· 二表的连接 表的连接是指在一个SQL语句中通过表与表之间的关联,从一个或多个表检索出相关的数据。连接是通过SQL语句中FROM从句的多个表名,以及WHERE从句里定义的表之间的连接条件来实现的。如果一个SQL语句的关联表超过两个,那么连接的顺序如何呢?ORACLE首先连接其中的两个表,产生一个结果集;然后将产生的结果集与下一个表再进行关联;继续这个过程,直到所有的表都连接完成;最后产生所需的数据。下面都以两个表的连接为例create table user_info(user_name char(10),user_id char(10));

Oracle -Update 多表关联

一条Update更新语句是不能更新多张表的,除非使用触发器隐含更新。而表的更新操作中,在很多情况下需要在表达式中引用要更新的表以外的数据。我们先来讨论根据其他表数据更新你要更新的表 一、MS SQL Server 多表关联更新 sql server提供了update的from 子句,可以将要更新的表与其它的数据源连接起来。虽然只能对一个表进行更新,但是通过将要更新的表与其它的数据源连接起来,就可以在update的表达式中引用要更新的表以外的其它数据。 一般形式: update A SET 字段1=B表字段表达式, 字段2=B表字段表达式 from B WHERE 逻辑表达式 例如: UPDATE dbo.Table2 SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB FROM dbo.Table2 INNER JOIN dbo.Table1 ON (dbo.Table2.ColA = dbo.Table1.ColA); 实际更新的操作是在要更新的表上进行的,而不是在from子句所形成的新的结果集上进行的 二、Oracle 多表关联更新 Oracle没有update from语法,可以通过两种实现方式: 1、利用子查询: update A SET 字段1=(select 字段表达 式 from B WHERE ...), 字段2=(select 字段表达式 from B WHERE ...) WHERE 逻辑表达式 UPDATE多个字段两种写法:

写法一: UPDATE table_1 a SET col_x1 = (SELECT b.col_y1, b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m), col_x2= (SELECT b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m) WHERE EXISTS(SELECT * FROM table_2 b WHERE b.col_n = a.col_m) 或 UPDATE table_1 a SET col_x1 = (SELECT b.col_y1, b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m), col_x2= (SELECT b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m) WHERE a.col_m=(SELECT b.col_n FROM table_2 b WHERE b.col_n = a.col_m) 写法二: UPDATE table_1 a SET(col_x1, col_x2)= (SELECT b.col_y1, b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m) WHERE EXISTS(SELECT * FROM table_2 b WHERE b.col_n = a.col_m); 或 UPDATE table_1 a SET(col_x1, col_x2)= (SELECT b.col_y1, b.col_y2 FROM table_2 b WHERE b.col_n = a.col_m) WHERE a.col_m=(SELECT b.col_n FROM table_2 b WHERE b.col_n = a.col_m)注意: 1. 对于子查询的值只能是一个唯一值,不能是多值。 2. 子查询在绝大多数情况下,最后面的where EXISTS子句是重要的,否则将得到错误的结果。且where EXISTS子句可用另一方法代替,如上。最后的子句是对a表被更新记录的限制,如无此句,对于a表中某记录,如在b表中关

Oracle+表连接方式(内连接-外连接-自连接)+详解

Oracle 表之间的连接分为三种: 1. 内连接(自然连接) 2. 外连接 (1)左外连接(左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接(左右两表都不加限制) 3. 自连接(同一张表内的连接) SQL的标准语法: select table1.column,table2.column from table1 [inner | left | right | full ] join table2 on table1.column1 = table2.column2; inner join 表示内连接; left join表示左外连接; right join表示右外连接; full join表示完全外连接; on子句用于指定连接条件。 注意: 如果使用from子句指定内、外连接,则必须要使用on子句指定连接条件; 如果使用(+)操作符指定外连接,则必须使用where子句指定连接条件。 一.内连接(Inner Join/Join) 1.1 Inner Join Inner join逻辑运算符返回满足第一个(顶端)输入与第二个(底端)输入联接的每一行。这个和用select查询多表是一样的效果,所以内连接用的很少。 还有一点要说明的就是Join 默认就是inner join。所以我们在写内连接的时候可以省略inner 这个关键字。1.2 下面举例来说明内连接: 1.2.1 先创建2张测试表并插入数据: SQL> select * from dave; ID NAME ---------- ---------- 1 dave 2 bl 1 bl 2 dave SQL> select * from bl; ID NAME ---------- ---------- 1 dave 2 bl 1.2.3 用内链接进行查询: SQL> Select a.id,https://www.wendangku.net/doc/6215640175.html,,https://www.wendangku.net/doc/6215640175.html, from dave a inner join bl b on a.id=b.id; -- 标准写法 ID NAME NAME ---------- ---------- ---------- 1 dave dave 2 bl bl 1 bl dave 2 dave bl

oracle两表查询练习附答案

Sutdent表的定义 字段名字段描述数据类型主键外键非空唯一自增Id学号INT(10)是否是是是Name姓名VARCHAR(20)否否是否否Sex性别VARCHAR(4)否否否否否Birth出生年份YEAR否否否否否Department院系VARCHAR(20)否否是否否Address家庭住址VARCHAR(50)否否否否否 Score表的定义 字段名字段描述数据类型主键外键非空唯一自增Id编号INT(10)是否是是是Stu_id学号INT(10)否否是否否C_name课程名VARCHAR(20)否否否否否Grade分数INT(10)否否否否否 1.创建student和score表 create table student( id number(10)not null primary key, name varchar2(20)not null, sex varchar2(4), birth number, department varchar2(20)not null, address varchar2(50) ); create table score( id number(10)not null primary key, stu_id number(10)not null, c_name varchar2(20), grade number(10) ); 2.为student表和score表增加记录 向student表插入记录的INSERT语句如下: Insert into student values(100101,'张三','男',23,'计算机系','北京市朝阳区'); Insert into student values(100102,'李四','男',21,'英语系','北京市海淀区'); Insert into student values(100103,'王五','女',19,'建工系','北京市昌平区'); Insert into student values(100104,'孙六','女',21,'化学系','北京市苏州桥'); Insert into student values(100105,'齐七','男',23,'英语系','北京市海淀区'); 向score表插入记录的INSERT语句如下: Insert into score values(001,100101,'计算机基础',89); Insert into score values(002,100101,'英语',93); Insert into score values(003,100101,'数学',87);

SQL、Oracle多表连接查询(内,外,交叉连接)

多表连接查询(内,外,交叉连接)连接查询实际上是通过各个表之间共同列的关联性来查询数据的,它是关系数据库查询最主要的特征. select 表1.字段名1,表2.字段名2,... from 表1,表2 where 连接条件 SQL-92标准所定义的FROM子句的连接语法格式为: FROM 表名join_type表名 [ON (连接条件)] 连接操作中的ON (连接条件) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑运算符等构成。 连接查询分类: 1.自连接查询,对同一个表进行连接操作(可以理解为两个不同表的内连接,有时可与嵌套查询等价) 2.内连接查询,<又分为:自然连接、等值连接、不等值连接三种> 3.外连接查询,<又分为:左外连接、右外连接、全外连接三种> 4.交叉连接查询,也作无条件查询。 5.联合查询 一.自连接查询: 一个表自己与自己建立连接称为自连接或自身连接。 进行自连接就如同两个分开的表一样,可以把一个表的某一行与同一表中的另一行连接起来。例: 查询选学“101”课程的成绩高于“9505201”号学生成绩的所有学生记录, 并按成绩从高到低排列。 select x.* from sclassx,sclass y where https://www.wendangku.net/doc/6215640175.html,o=''101'' and x.degree>y.degree and y.sno=''9505201'' and https://www.wendangku.net/doc/6215640175.html,o=''101'' order by x.degreedesc 二. 内连接查询 内连接(INNER JOIN)使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。 1、等值连接: 所谓等值连接,是指表之间通过“等于”关系连接起来,产生一个临时表, 然后对该临时表进行处理后生成最终结果。其查询结果中列出被连接表中的所有列,包括其中的重复列。 SELECT * FROM authors AS a INNER JOIN publishers AS p ON a.city=p.city

Oracle 表三种连接方式使用介绍(sql优化)

1. NESTED LOOP 对于被连接的数据子集较小的情况,nested loop连接是个较好的选择。nested loop就是扫描一个表,每读到一条记录,就根据索引去另一个表里面查找,没有索引一般就不会是nested loops。一般在nested loop中,驱动表满足条件结果集不大,被驱动表的连接字段要有索引,这样就走nstedloop。如果驱动表返回记录太多,就不适合nested loops了。如果连接字段没有索引,则适合走hash join,因为不需要索引。 可用ordered提示来改变CBO默认的驱动表,可用USE_NL(table_name1 table_name2)提示来强制使用nested loop。 要点如下: 1)对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择 2)使用USE_NL(table_name1 table_name2)可是强制CBO 执行嵌套循环连接 3)Nested loop一般用在连接的表中有索引,并且索引选择性较好的时候 4)OIN的顺序很重要,驱动表的记录集一定要小,返回结果集的响应时间是最快的。 5)Nested loops 工作方式是从一张表中读取数据,访问另一张表(通常是索引)来做匹配,nested loops适用的场合是当一个关联表比较小的时候,效率会更高。 2. HASH JOIN hash join是CBO 做大数据集连接时的常用方式。优化器扫描小表(数据源),利用连接键(也就是根据连接字段计算hash 值)在内存中建立hash表,然后扫描大表,每读到一条记录就探测hash表一次,找出与hash表匹配的行。 当小表可以全部放入内存中,其成本接近全表扫描两个表的成本之和。如果表很大不能完全放入内存,这时优化器会将它分割成若干不同的分区,不能放入内存的部分就把该分区写入磁盘的临时段,此时要有较大的临时段从而尽量提高I/O 的性能。临时段中的分区都需要换进内存做hash join。这时候成本接近于全表扫描小表+分区数*全表扫描大表的代价和。 至于两个表都进行分区,其好处是可以使用parallel query,就是多个进程同时对不同的分区进行join,然后再合并。但是复杂。 使用hash join时,HASH_AREA_SIZE初始化参数必须足够的大,如果是9i,Oracle建议使用SQL工作区自动管理,设置WORKAREA_SIZE_POLICY 为AUTO,然后调整PGA_AGGREGATE_TARGET即可。 以下条件下hash join可能有优势: 1)两个巨大的表之间的连接。 2)在一个巨大的表和一个小表之间的连接。 要点如下: 1)散列连接是CBO 做大数据集连接时的常用方式. 2)也可以用USE_HASH(table_name1 table_name2)提示来强制使用散列连接 3)Hash join在两个表的数据量差别很大的时候. 4)Hash join的工作方式是将一个表(通常是小一点的那个表)做hash运算并存储到hash列表中,从另一个表中抽取记录,做hash运算,到hash 列表中找到相应的值,做匹配。 可用ordered提示来改变CBO默认的驱动表,可用USE_HASH(table_name1 table_name2)提示来强制使用hash join。 3. SORT MERGE JOIN a)对连接的每个表做table access full;

ORACLE 多表关联 UPDATE 语句

为了方便起见,建立了以下简单模型,和构造了部分测试数据: 在某个业务受理子系统BSS中, SQL 代码 1.--客户资料表 2.create table customers 3.( 4.customer_id number(8) not null, -- 客户标示 5.city_name varchar2(10) not null, -- 所在城市 6.customer_type char(2) not null, -- 客户类型 7.... 8.) 9.create unique index PK_customers on customers (customer_id) 由于某些原因,客户所在城市这个信息并不什么准确,但是在 客户服务部的CRM子系统中,通过主动服务获取了部分客户20%的所在城市等准确信息,于是你将该部分信息提取至一张临时表中: SQL 代码

1) 最简单的形式 SQL 代码 2) 两表(多表)关联update -- 仅在where字句中的连接SQL 代码 3) 两表(多表)关联update -- 被修改值由另一个表运算而来SQL 代码

注意在这个语句中, =(select b.city_name,b.customer_type from tmp_cust_city b where b.customer_id=a.customer_id ) 与 (select 1 from tmp_cust_city b where b.customer_id=a.customer_id) 是两个独立的子查询,查看执行计划可知,对b表/索引扫描了2篇;如果舍弃where条件,则默认对A表进行全表 更新,但由于 SQL 代码

ORACLE 多表关联 UPDATE 语句

ORACLE 多表关联UPDATE 语句 为了方便起见,建立了以下简单模型,和构造了部分测试数据: 在某个业务受理子系统BSS中, --客户资料表 create table customers ( customer_id number(8) not null, -- 客户标示 city_name varchar2(10) not null, -- 所在城市 customer_type char(2) not null, -- 客户类型 ... ) create unique index PK_customers on customers (customer_id) 由于某些原因,客户所在城市这个信息并不什么准确,但是在 客户服务部的CRM子系统中,通过主动服务获取了部分客户20%的所在 城市等准确信息,于是你将该部分信息提取至一张临时表中: create table tmp_cust_city ( customer_id number(8) not null, citye_name varchar2(10) not null, customer_type char(2) not null ) 1) 最简单的形式 --经确认customers表中所有customer_id小于1000均为'北京' --1000以内的均是公司走向全国之前的本城市的老客户:) update customers set city_name='北京' where customer_id<1000 2) 两表(多表)关联update -- 仅在where字句中的连接 --这次提取的数据都是VIP,且包括新增的,所以顺便更新客户类别update customers a -- 使用别名 set customer_type='01' --01 为vip,00为普通 where exists (select 1 from tmp_cust_city b where b.customer_id=a.customer_id ) 3) 两表(多表)关联update -- 被修改值由另一个表运算而来 update customers a -- 使用别名 set city_name=(select b.city_name from tmp_cust_city b where b.customer_id=a.customer_id) where exists (select 1

Oracle数据库表连接方式及常见用法

Oracle数据库表连接方式及常见用法 racle数据库表连接方式根据应用场景的不同会有不同的方法,本文向您介绍相等连接、外连接、不等连接、自连接和哈希连接等。一个SQL语句的关联表超过两个,那么连接的顺序如何呢?ORACLE首先连接其中的两个表,产生一个结果集;然后将产生的结果集与下一个表再进行关联;继续这个过程,直到所有的表都连接完成;最后产生所需的数据,,本文将主要从以下几个典型的例子来分析Orac Oracle数据库表连接方式根据应用场景的不同会有不同的方法,本文向您介绍相等连接、外连接、不等连接、自连接和哈希连接等。 一个SQL语句的关联表超过两个,那么连接的顺序如何呢?ORACLE首先连接其中的两个表,产生一个结果集;然后将产生的结果集与下一个表再进行关联;继续这个过程,直到所有的表都连接完成;最后产生所需的数据,,本文将主要从以下几个典型的例子来分析Oracle表的几种不同连接方式: 1. 相等连接 通过两个表具有相同意义的列,可以建立相等连接条件。 只有连接列上在两个表中都出现且值相等的行才会出现在查询结果中。 例查询员工信息以及对应的员工所在的部门信息; SELECT * FROM EMP,DEPT; SELECT * FROM EMP,DEPT WHERE EMP.DEPTNO = DEPT.D EPTNO; REM 显示工资超过2000的员工信息以及对应的员工的部门名称。 2. 外连接 对于外连接,Oracle中可以使用“(+)”来表示,9i可以使用LEFT/RIGHT/FULL OUTER JOIN,下面将配合实例一一介绍。除了显示匹配相等连接条件的信息之外,还显示无法匹配相等连接条件的某个表的信息。 外连接采用(+)来识别。 ◆左条件(+) = 右条件; 代表除了显示匹配相等连接条件的信息之外,还显示右条件所在的表中无法匹配相等连接条件的信息。 此时也称为"右外连接".另一种表示方法是:

ORACLE_多表连接与子查询2

ORACLE 多表连接与子查询 Oracle表连接 SQL/Oracle使用表连接从多个表中查询数据 语法格式: select字段列表 from table1,table2 where table1.column1=table2.column2; Select 字段列表 From table1,table2 Where table1,column1 = table2.column2; 说明: 在where子句中指定连接条件 当被连接的多个表中存在同名字段时,必须在该字段前加上"表名"作为前缀.连接的类型 Oracle8i之前的表连接: 等值连接(Equijoin) 非等值连接(Non-Equijoin) 外连接(Outer join):-->左外连接-->右外连接 自连接(Self join) Oracle9之后新引入的连接形式(支持SQL99规范)

交叉连接(Cross join) 自然连接(Natural join) 使用Using子句建立连接 使用on子句建立连接 外连接(Outer join):-->左外连接-->右外连接-->全外连接 等值连接(Equijoin) select empno,ename,sal,emp.deptno,dname from emp,dept where emp.deptno = dept.deptno; 多表连接中: ?可使用AND操作符增加查询条件 ?使用表别名可以简化查询 ?使用表名(表别名)前缀可提高查询效率 ?为了连接n个表,至少需要n-1个连接条件 非等值连接(Non-Equijoin) 外连接(Outer join) 使用外连接可以看到参与连接的某一方不满足连接条件的记录 外连接运算符为(+) 传统的外连接分为左外连接和右外连接两种 语法格式: select字段列表 from table1,table2 where table1.column1(+)=table2.column2;

几种常用的表连接方式

1.1.1嵌套循环连接 在嵌套循环连接中,Oracle从第一个行源中读取第一行,然后和第二个行源中的数据进行对比。所有匹配的记录放在结果集中,然后Oracle将读取第一个行源中的下一行。按这种方式直至第一个数据源中的所在行都经过处理。第一个记录源通常称为外部表,或者驱动表,相应的第二个行源称为内部表。使用嵌套循环连接是一种从连接结果中提取第一批记录的最快速的方法。 在驱动行源表(就是您正在查找的记录)较小、或者内部行源表已连接的列有惟一的索引或高度可选的非惟一索引时, 嵌套循环连接效果是比较理想的。嵌套循环连接比其他连接方法有优势,它可以快速地从结果集中提取第一批记录,而不用等待整个结果集完全确定下来。这样,在理想情况下,终端用户就可以通过查询屏幕查看第一批记录,而在同时读取其他记录。不管如何定义连接的条件或者模式,任何两行记录源可以使用嵌套循环连接,所以嵌套循环连接是非常灵活的。 然而,如果内部行源表(读取的第二张表)已连接的列上不包含索引,或者索引不是高度可选时, 嵌套循环连接效率是很低的。如果驱动行源表(从驱动表中提取的记录)非常庞大时,其他的连接方法可能更加有效。 图1-1说明了程序清单1-1中查询执行的方法。

select /*+ordered*/ename,dept.deptno from dept,emp where dept.deptno=emp.deptno 1.1.2排列合并连接 在排列合并连接中,Oracle分别将第一个源表、第二个源表按它们各自要连接的列排序,然后将两个已经排序的源表合并。如果找到匹配的数据,就放到结果集中。 在缺乏数据的选择性或者可用的索引时,或者两个源表都过于庞大(超过记录数的5%)时,排序合并连接将比嵌套循环连更加高效。但是,排列合并连接只能用于等价连接(WHERE D.deptno=E.dejptno,而不是WHERE D.deptno>=E.deptno)。排列

Oracle中表的连接及其调整

Oracle中表的连接及其调整 只有对这些问题有了清晰的理解后,我们才能针对特定的查询需求选择合适的连接方式,开发出健壮的数据库应用程序。选择合适的表连接方法对SQL语句运行的性能有着至关重要的影响。下面我们就Oracle常用的一些连接方法及适用情景做一个简单的介绍。 常用的表连接方式: a.嵌套循环连接(Nested Loop) b.排序合并连接(Sort Merge) c. 哈希连接(Hash join) 一、嵌套循环连接(Nested Loop) 嵌套循环连接的工作方式是这样的: 1、Oracle首先选择一张表作为连接的驱动表,这张表也称为外部表(Outer Table)。由驱动表进行驱动连接的表或数据源称为内部表(Inner Table)。 2、提取驱动表中符合条件的记录,与被驱动表的连接列进行关联查询符合条件的记录。在这个过程中,Oracle首先提取驱动表中符合条件的第一条记录,再与内部表的连接列进行关联查询相应的记录行。在关联查询的过程中,Oracle 会持续提取驱动表中其他符合条件的记录与内部表关联查询。这两个过程是并行进行的,因此嵌套循环连接返回前几条记录的速度是非常快的。在这里需要说明的是,由于Oracle最小的IO单位为单个数据块,因此在这个过程中Oracle会首先提取驱动表中符合条件的单个数据块中的所有行,再与内部表进行关联连接查询的,然后提取下一个数据块中的记录持续地循环连接下去。当然,如果单行记录跨越多个数据块的话,就是一次单条记录进行关联查询的。 3、嵌套循环连接的过程如下所示: 我们可以看出这里面存在着两个循环,一个是外部循环,提取驱动表中符合条件的每条记录。另外一个是内部循环,根据外循环中提取的每条记录对内部表进行

Oracle 多表检索

Oracle 多表检索 在实际应用中,经常会碰到需要检索的数据存在于两个或两个以上的表中。这时就需要使用SELECT语句执行多表检索。多表检索操作比单表检索复杂得多。为了更好地理解多表检索操作,需要理解表的别名,笛卡尔积、内连接、外连接、自然连接和交叉连接等概念。 1.表的别名 在多表查询时,如果多个表之间存在同名的列,则必须使用表名来限定列引用。例如,在SCOTT模式中,EMP表和DEPT表中都存在DEPTNO列,在进行多表检索时就是根据该列连接两个表。 然而,随着查询变得越来越复杂,语句会由于每次限定列时输入表名而变得冗长乏味。因此,SQL语言提供了另一种机制——表别名。表的别名是在SELECT语句中为表定义的临时性名称,以简化对表的引用。 下面的示例将使用表别名来实现多表的检索。 (1)以SCOTT身份连接系统。 (2)使用SELECT语句检索EMP和DEPT表,查询属于某一个部门的职工信息。在该检索中,没有使用表的别名,因此在WHERE子句中需要使用表的全名称对列进行限定。 SQL> select ename 姓名,job 职位,sal 工资,dname 部门 2 from emp,dept 3 where emp.deptno=dept.deptno 4 and dept.dname='SALES'; 姓名职位工资部门 ---------- --------- ---------- -------------- ALLEN SALESMAN 1600 SALES WARD SALESMAN 1250 SALES MARTIN SALESMAN 1250 SALES BLAKE MANAGER 2850 SALES TURNER SALESMAN 1500 SALES JAMES CLERK 950 SALES 已选择6行。 (3)使用SELECT语句查询EMP和DEPT表,同样查询属于某一个部门的职工信息。只是在该SELECT语句中为每个表指定了别名,并通过不同的列别名引用表。EMP表的别名为E,而DEPT表的别名为D。为表定义别名后,在SELECT语句的任何地方都可以使用E和D引用相应的表。 SQL> select e.ename 姓名,e.job 职位,e.sal 工资,d.dname 部门 2 from emp e,dept d 3 where e.deptno=d.deptno 4 and d.dname='SALES'; 姓名职位工资部门 ---------- --------- ---------- --------------

oracle多表连接查询性能优化

原始SQL语句如下: select * from (select c.product_name, a.prd_inst_name, https://www.wendangku.net/doc/6215640175.html, prd_state, a.accept_date, https://www.wendangku.net/doc/6215640175.html, basic_state, a.evolution_pty_id, decode(a.if_prepay, 1, '是', '否') prepay, a.install_addr, a.install_date, a.service_nbr, a.ofr_id, https://www.wendangku.net/doc/6215640175.html, ofr_name, d.cust_name, rownum num from crm_tb_prd_prd_inst a, crm_tb_prd_prd c, crm_tb_pty_cust d, m_prd_inst_stas m, m_prd_inst_base_state m1, m_prdmark_inst_base_state m2, ext_crm_tb_prd_prd_inst ext where a.prd_id = c.product_id and m.gwm_fid(+) = a.prd_inst_stas_id and m1.basic_state(+) = a.basic_state and m2.ofr_id(+) = a.ofr_id and a.prd_inst_id(+) = ext.prd_inst_id and d.cust_id(+) = a.own_cust_id and ext.building_fid = 693253 and rownum <= 10) where num > 0; 数据库中,a、c、d 三张表中数据十万数量级,每查询一次,时间约为75s。 查询表结构,发现a表关联的m表的外键ofr_id ,m1表的外键basic_state,d表的外键own_cust_id均无索引,为其添加索引。 索引添加后,执行速度提升为53s左右,效果仍不明显。 分析查询语句,发现查询时使用了 rownum 做分页查询的控制条件。当多表连接查询时,oracle数据库会自动检查每一张表的rownum,

详解Oracle多种表连接方式

ORACLE 多表连接与子查询 连接的类型 Oracle8i之前的表连接: 等值连接(Equijoin) 非等值连接(Non-Equijoin) 外连接(Outer join):-->左外连接-->右外连接 自连接(Self join) Oracle9之后新引入的连接形式(支持SQL99规范) 交叉连接(Cross join) 自然连接(Natural join) 使用Using子句建立连接 使用on子句建立连接 外连接(Outer join):-->左外连接-->右外连接-->全外连接 oracle中的连接可分为, 1. 内连接(自然连接) 2. 外连接 (1)左外连接(左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接(左右两表都不加限制) 3. 自连接(同一张表内的连接) 4、交叉连接(cross join) (即笛卡尔积) 5、其他连接定义(可能属于上面3种中的某一种) (1)等值连接(equijoin) (2)非等值连接(non-equijoin) (3)on建立查询连接 (4)using 建立查询连接 SQL的标准语法: 多表连接使用SQL99连接语法,两个以上的表进行连接时应依次/分别指定相临的两个表之间的连接条件. select字段列表 from table1 [cross join table2]| [natural join table2]| [join table2 using(字段名)]| [join table2 on(table.column_name=table2.column_name)]| [(left | right | full out ) join table2 on(table1.column_name=table2.column_name)] [cross join table3]| [natural join table3]| [join table3 using(字段名)]|

oracle多表关联的优化问题演示教学

o r a c l e多表关联的优 化问题

ORACLE多表查询优化 ORACLE多表查询优化 这里提供的是执行性能的优化,而不是后台数据库优化器资料: 参考数据库开发性能方面的各种问题,收集了一些优化方案统计如下(当然,象索引等优化方案太过简单就不列入了,嘿嘿): 执行路径:ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用:我们发现,单表数据的统计比多表统计的速度完全是两个概念.单表统计可能只要0.02秒,但是2张表联合统计就可能要几十表了.这是因为ORACLE只对简单的表提供高速缓冲(cache buffering) ,这个功能并不适用于多表连接查询..数据库管理员必须在init.ora中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了. 当你向ORACLE提交一个SQL语句,ORACLE会首先在这块内存中查找相同的语句. 这里需要注明的是,ORACLE对两者采取的是一种严格匹配,要达成共享,SQL语句必须 完全相同(包括空格,换行等). 共享的语句必须满足三个条件: A. 字符级的比较: 当前被执行的语句和共享池中的语句必须完全相同. 例如: SELECT * FROM EMP; 和下列每一个都不同 SELECT * from EMP; Select * From Emp; SELECT * FROM EMP; B. 两个语句所指的对象必须完全相同:

用户对象名如何访问 Jack sal_limit private synonym Work_city public synonym Plant_detail public synonym Jill sal_limit private synonym Work_city public synonym Plant_detail table owner 考虑一下下列SQL语句能否在这两个用户之间共享. SQL 能否共享原因 select max(sal_cap) from sal_limit; 不能每个用户都有一个private synonym - sal_limit , 它们是不同的对象 select count(*) from work_city where sdesc like 'NEW%'; 能两个用户访问相同的对象public synonym - work_city select a.sdesc,b.location from work_city a , plant_detail b where a.city_id = b.city_id 不能用户jack 通过private synonym访问 plant_detail 而jill 是表的所有者,对象不同. C. 两个SQL语句中必须使用相同的名字的绑定变量(bind variables) 例如:第一组的两个SQL语句是相同的(可以共享),而第二组中的两个语句是不同的(即使在运行时,赋于不同的绑定变量相同的值) a. select pin , name from people where pin = :blk1.pin; select pin , name from people where pin = :blk1.pin;

oracle数据库表左连接右连接全连接的认识

1.首先还是说明一下,为什么要使用连接(join)?原因有两点: 1)经常有需要访问多个表中字段的情况 2)用子查询也可以实现上面的功能,但是效率相当低下。使用连接可以大大提高效率。 2.连接(Join)的基本结构: select ... from table1 t1 join table2 t2 on ti.id = t2.id; join前后是两个需要连接的表,on表示的是连接的条件。传统的写法是不使用join 关键字,使用where表示条件: select ... from table1 t1, table2 t2 where ti.id = t2.id; 一般是两个表进行连接,三个表的连接语法稍有不同: 普通写法:select ... from a join b on a.id = b.id join c on b.id = c.id; 传统写法:select ... from a, b, c where a.id = b.id and b.id = c.id; 3.连接的分类: 1. 对等连接 上面的就是一种对等连接,即默认的join方式。特点是只显示连接的表中存在而且相等的记录。其它的 记录均不显示。 传统的写法也是一种对等连接,只显示匹配条件的记录。

2. 左/右连接 有时需要将进行连接的其中一个表作为基准显示全部的数据,根据连接条件在其它表中可能会出现无法 匹配的数据,此时就用空值来代替。比如显示员工信息时,有的员工可能还没有分配到某个具体的部门 (新进员工),其所属部门一项就没有数据,但是员工仍然需要显示,即员工表数据需要全部显示。 具体语法: select ... from table1 t1 left join table2 t2 on ti.id = t2.id; --左连接 或 select ... from table1 t1 right join table2 t2 on ti.id = t2.id; --右连接 左还是右的区别,简单地说左(右)连接就是指join的左(右)边是基准表,全部数据都要显示,根据 连接条件无法进行连接的记录就用空值代替。 比如: select e.empno, e.ename, d.dname from emp e left join dept d on e.deptno = d.deptno; 还没有分配到某个具体的部门的员工的e.deptno肯定是没有值的,无法满足 “e.deptno = d.deptno”的 条件,但由于是左连接,左边的员工表的数据必然会显示,这时该员工的部门名称就是空值。 若是right join ... on,就表示部门表的数据全部显示,员工表中无法连接的数据就是空值代替,意思 就是说这个部门还没有员工,因为在员工表中没有一条记录的deptno与该部门的deptno相匹配(可能是 刚刚成立的新部门)

oracle多表关联的优化问题

ORACLE多表查询优化 ORACLE多表查询优化 这里提供的就是执行性能的优化,而不就是后台数据库优化器资料: 参考数据库开发性能方面的各种问题,收集了一些优化方案统计如下(当然,象索引等优化方案太过简单就不列入了,嘿嘿): 执行路径:ORACLE的这个功能大大地提高了SQL的执行性能并节省了内存的使用:我们发现,单表数据的统计比多表统计的速度完全就是两个概念、单表统计可能只要0、02秒,但就是2张表联合统计就可能要几十表了、这就是因为ORACLE 只对简单的表提供高速缓冲(cache buffering) ,这个功能并不适用于多表连接查询、、数据库管理员必须在init、ora中为这个区域设置合适的参数,当这个内存区域越大,就可以保留更多的语句,当然被共享的可能性也就越大了、 当您向ORACLE提交一个SQL语句,ORACLE会首先在这块内存中查找相同的语句、 这里需要注明的就是,ORACLE对两者采取的就是一种严格匹配,要达成共享,SQL 语句必须 完全相同(包括空格,换行等)、 共享的语句必须满足三个条件: A、字符级的比较: 当前被执行的语句与共享池中的语句必须完全相同、 例如: SELECT * FROM EMP; 与下列每一个都不同 SELECT * from EMP; Select * From Emp; SELECT * FROM EMP; B、两个语句所指的对象必须完全相同: 用户对象名如何访 问 Jack sal_limit private synonym Work_city public synonym Plant_detail public synonym Jill sal_limit private

相关文档