ORACLE的SQL JOIN方式小结

在ORACLE数据库中,表与表之间的SQL JOIN方式有多种(不仅表与表,还可以表与视图、物化视图等联结),官方的解释如下所示

 

A join is a query that combines rows from two or more tables, views, or materialized views. Oracle Database performs a join whenever multiple tables appear in the FROM clause of the query. The select list of the query can select any columns from any of these tables. If any two of these tables have a column name in common, then you must qualify all references to these columns throughout the query with table names to avoid ambiguity.

 

SQL JOIN 归纳起来有下面几种方式,下面一起来梳理一下这些概念。SQL JOIN其实是一个逻辑概念,像NEST LOOP JOIN、 HASH JOIN等是表连接的物理实现方式。

 

 

我们先准备一个两个测试表M与N(仅仅是为了演示需要),如下脚本所示

SQL> CREATE TABLE M
  2  (
  3       NAME       VARCHAR2(12)
  4      ,SEX        VARCHAR2(6)
  5  );
 
Table created.
 
SQL> CREATE TABLE N
  2  (
  3         NAME       VARCHAR2(12)
  4      ,GRADE      NUMBER(2)
  5  );
 
Table created.
 
SQL> INSERT INTO M
  2  SELECT 'kerry', 'male'   FROM DUAL UNION ALL
  3  SELECT 'jimmy', 'male'   FROM DUAL UNION ALL
  4  SELECT 'tina' , 'female' FROM DUAL UNION ALL
  5  SELECT 'wendy', 'female' FROM DUAL;
 
4 rows created.
 
SQL> COMMIT;
 
Commit complete.
 
SQL> INSERT INTO N
  2  SELECT 'kerry',  3 FROM DUAL UNION ALL
  3  SELECT 'jimmy',  2 FROM DUAL UNION ALL
  4  SELECT 'ken'  ,  6 FROM DUAL UNION ALL
  5  SELECT 'richard',5 FROM DUAL;
 
4 rows created.
 
SQL> COMMIT;
 
Commit complete.

 

内连接:INNER JOIN

 

INNER JOIN 它表示返回两个表或记录集连接字段的匹配记录。如下所示,INNER JOIN 可以有三种实现方式:

 

SQL> SELECT M.NAME, M.SEX, N.GRADE 
  2  FROM M INNER JOIN N ON M.NAME=N.NAME;
 
NAME         SEX         GRADE
------------ ------ ----------
kerry        male            3
jimmy        male            2
 
SQL> SELECT M.NAME, M.SEX, N.GRADE
  2  FROM M, N 
  3  WHERE M.NAME=N.NAME;
 
NAME         SEX         GRADE
------------ ------ ----------
kerry        male            3
jimmy        male            2

 

 

第三种方式,使用USING,如下所示,这种写法一般较少人使用。

 

SQL> SELECT NAME, M.SEX,N.GRADE
  2  FROM M INNER JOIN N USING(NAME);
 
NAME         SEX         GRADE
------------ ------ ----------
kerry        male            3
jimmy        male            2
 
SQL> 

 

注意,INNER JOIN可以用使用简写JOIN方式,如下所示,但是建议使用INNER JOIN 而不是JOIN这样的语法。

 

 

如果我们用韦恩图来解释INNER JOIN,则非常一目了然、形象生动。可以用下面图来表示(此图以及下面的韦恩图均来自链接http://pafumi.net/SQL_Joins.html ,本来想自己画,无奈有些图使用word不好实现,R语言不会。故在此借其图用用)

 

 

 

外连接:OUTER JOIN

 

1 全连接:full join

全连接 :包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行。不符合条件的,以空值代替。如下所示:

 
SQL> SELECT M.NAME, N.NAME, M.SEX, N.GRADE
  2  FROM M FULL OUTER JOIN N ON M.NAME=N.NAME;
 
NAME         NAME         SEX         GRADE
------------ ------------ ------ ----------
kerry        kerry        male            3
jimmy        jimmy        male            2
             ken                          6
             richard                      5
tina                      female
wendy                     female
 
6 rows selected.

 

FULL OUTER JOIN的韦恩图如下所示:

 

 

 

2 左外连接:LEFT JOIN

 

左外连接又叫左连接 :意思是包含左边表所有记录,右边所有的匹配的记录,如果没有则用空补齐。换句话说就是,列出左边表全部的,及右边表符合条件的,不符合条件的以空值代替。

SQL> SELECT M.NAME, N.NAME, M.SEX, N.GRADE
  2  FROM M LEFT OUTER JOIN N ON M.NAME=N.NAME;
 
NAME         NAME         SEX         GRADE
------------ ------------ ------ ----------
kerry        kerry        male            3
jimmy        jimmy        male            2
tina                      female
wendy                     female
 
SQL> SELECT M.NAME, N.NAME, M.SEX, N.GRADE
  2  FROM M LEFT JOIN N ON M.NAME=N.NAME;
 
NAME         NAME         SEX         GRADE
------------ ------------ ------ ----------
kerry        kerry        male            3
jimmy        jimmy        male            2
tina                      female
wendy                     female

 

 

在ORACLE 9i以及之前,使用在(+)来表示左连接,哪个带(+)哪个需要条件符合的,另一个全部的。即放左表示右连接,放右表示左连接。这种写法,如果不熟悉,就会有点陌生。其实也不是什么新鲜事物,只是你不太熟悉而已。

 
SQL> SELECT M.NAME, N.NAME, M.SEX, N.GRADE
  2  FROM M, N
  3  WHERE M.NAME=N.NAME(+);
 
NAME         NAME         SEX         GRADE
------------ ------------ ------ ----------
kerry        kerry        male            3
jimmy        jimmy        male            2
tina                      female
wendy                     female
SQL> 

 

LEFT OUTER JOIN的韦恩图如下所示:

 

 

3 右外连接:RIGHT JOIN

 

右外连接又叫右连接: 意思是包括右边表所有记录,匹配左边表的记录,如果没有则以空补齐,换句话说,与左连接一样,列出右边表全部的,及左边表符合条件的,不符合条件的用空值替代。如下所示

SQL> SELECT M.NAME, N.NAME, M.SEX, N.GRADE
  2  FROM M RIGHT OUTER JOIN N ON M.NAME=N.NAME;
 
NAME         NAME         SEX         GRADE
------------ ------------ ------ ----------
kerry        kerry        male            3
jimmy        jimmy        male            2
             ken                          6
             richard                      5
 
SQL> SELECT M.NAME, N.NAME, M.SEX, N.GRADE
  2  FROM M RIGHT JOIN N ON M.NAME=N.NAME;
 
NAME         NAME         SEX         GRADE
------------ ------------ ------ ----------
kerry        kerry        male            3
jimmy        jimmy        male            2
             ken                          6
             richard                      5
 
SQL> SELECT M.NAME, N.NAME, M.SEX, N.GRADE
  2  FROM M, N
  3  WHERE M.NAME(+) = N.NAME;
 
NAME         NAME         SEX         GRADE
------------ ------------ ------ ----------
kerry        kerry        male            3
jimmy        jimmy        male            2
             ken                          6
             richard                      5

 

 

笛卡尔积:CROSS JOIN

 

CROSS JOIN就是笛卡尔乘积连接,不需要任何关联条件,实现M*N的结果集,其实这种SQL JOIN方式基本上只在理论上有意义,实际当中,很少有用的CORSS JOIN方式。

注意: cross join跟inner join、outer join等有所不同,不需要关键词on,因为它不需要相关字段做关联。

SQL> SELECT M.NAME, M.SEX, N.NAME,N.GRADE
  2  FROM M CROSS JOIN N;
 
NAME         SEX    NAME              GRADE
------------ ------ ------------ ----------
kerry        male   kerry                 3
kerry        male   jimmy                 2
kerry        male   ken                   6
kerry        male   richard               5
jimmy        male   kerry                 3
jimmy        male   jimmy                 2
jimmy        male   ken                   6
jimmy        male   richard               5
tina         female kerry                 3
tina         female jimmy                 2
tina         female ken                   6
 
NAME         SEX    NAME              GRADE
------------ ------ ------------ ----------
tina         female richard               5
wendy        female kerry                 3
wendy        female jimmy                 2
wendy        female ken                   6
wendy        female richard               5
 
16 rows selected.

注意:笛卡尔积用维恩图是无法体现出来的。

 

自然连接:NATURAL JOIN

 

NATURAL JOIN: 在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。如下所示

SQL> SELECT * FROM M NATURAL JOIN N;
 
NAME         SEX         GRADE
------------ ------ ----------
kerry        male            3
jimmy        male            2

官方解释:

The NATURAL keyword indicates that a natural join is being performed. A natural join is based on all columns in the two tables that have the same name. It selects rows from the two tables that have equal values in the relevant columns. When specifying columns that are involved in the natural join, do not qualify the column name with a table name or table alias

 

有种说法是,对两张表中字段名和数据类型都相同的字段进行等值连接,并返回符合条件的结果 ,其实只要字段名相同,数据类型不同,也可以做NATURAL JOIN,如下所示:

SQL> CREATE TABLE TEST1
  2  (         
  3     ID     NUMBER(10),
  4     NAME   VARCHAR2(12)
  5  );
 
Table created.
 
SQL>  CREATE TABLE TEST2
  2  (
  3    ID    VARCHAR2(10),
  4     NT    VARCHAR2(12)
  5  );
 
Table created.
 
SQL> INSERT INTO TEST1
  2  VALUES(1000, 'KERRY');
 
1 row created.
 
SQL> COMMIT;
 
Commit complete.
 
SQL> INSERT INTO TEST2
  2  VALUES('1000', 'KKK');
 
1 row created.
 
SQL> SELECT * FROM TEST1 NATURAL JOIN TEST2;
 
ID         NAME         NT
---------- ------------ ------------
1000       KERRY        KKK
 
SQL> 

 

自然连接的两个表的有多个字段都满足有相同名称,那么他们会被作为自然连接的条件,如下案例所示

SQL> DROP TABLE TEST1;
 
Table dropped.
 
SQL> DROP TABLE TEST2;
 
Table dropped.
 
SQL> CREATE TABLE TEST1
  2  (
  3     ID     NUMBER(10),
  4     NAME   VARCHAR2(12)
  5  )
  6  ;
 
Table created.
 
SQL> CREATE TABLE TEST2
  2  (
  3    ID    NUMBER(10),
  4    NAME  VARCHAR2(12)
  5  );
 
Table created.
 
SQL> INSERT INTO TEST1
  2  SELECT 1000, 'KERRY' FROM DUAL UNION ALL
  3  SELECT 1001, 'KEN'   FROM DUAL;
 
2 rows created.
 
SQL> COMMIT;
 
Commit complete.
 
SQL> INSERT INTO TEST2
  2  SELECT 1000, 'KKK' FROM DUAL UNION ALL
  3  SELECT 1001, 'KEN' FROM DUAL;
 
2 rows created.
 
SQL> COMMIT;
 
Commit complete.
 
SQL> SELECT * FROM TEST1 NATURAL JOIN TEST2;
 
        ID NAME
---------- ------------
      1001 KEN

 

NATURAL JOIN的韦恩图,其实和内连接是一样的。如下所示:

 

SEMI JOIN

 

  SEMI JOIN 多在子查询exists中使用,对外部row source的每个键值,查找到内部row source匹配的第一个键值后就返回,如果找到就不用再查找内部row source其他的键值了。官方介绍案例如下

 

Using Semijoins: Example

 

In the following example, only one row needs to be returned from the departments table, even though many rows in the employees table might match the subquery. If no index has been defined on thesalary column in employees, then a semijoin can be used to improve query performance.

 

SELECT * FROM departments

 

   WHERE EXISTS

 

   (SELECT * FROM employees

 

       WHERE departments.department_id = employees.department_id

 

       AND employees.salary > 2500)

 

   ORDER BY department_name;

 

 

ANTI JOIN

 

ANTI JOIN多用于!=或not in 等查询;如果找到满足条件(!=   not in)的不返回,不满足条件(!=   not in)的返回。和join相反。

 

 

Using Antijoins: Example

 

The following example selects a list of employees who are not in a particular set of departments:

 

SELECT * FROM employees

 

   WHERE department_id NOT IN

 

   (SELECT department_id FROM departments

 

       WHERE location_id = 1700)

 

   ORDER BY last_name;

 

 

 

SELF JOIN

 

SELF JOIN其实就是某个表和其自身连接,连接方式可以是内连接,外连接,交叉连接

 

 

Using Self Joins: Example 

 

The following query uses a self join to return the name of each employee along with the name of the employee's manager. A WHERE clause is added to shorten the output.

 

SELECT e1.last_name||' works for '||e2.last_name

 

   "Employees and Their Managers"

 

   FROM employees e1, employees e2

 

   WHERE e1.manager_id = e2.employee_id

 

      AND e1.last_name LIKE 'R%';

 

 

 

 

Employees and Their Managers  

 

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

 

Rajs works for Mourgos

Raphaely works for King

Rogers works for Kaufling

Russell works for King

 

参考资料:

https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries006.htm

http://pafumi.net/SQL_Joins.html

http://www.itpub.net/thread-420946-1-1.html

 

 

时间: 2024-10-28 14:40:48

ORACLE的SQL JOIN方式小结的相关文章

SQL Server Join方式

原文:SQL Server Join方式 0.参考文献 Microsoft SQL Server企业级平台管理实践  看懂SqlServer查询计划 1.测试数据准备 参考:Sql Server中的表访问方式Table Scan, Index Scan, Index Seek 这篇博客中的实验数据准备.这两篇博客使用了相同的实验数据. 2.SQL Server中的三种Join方式 在Sql Server中,每一个join命令,在内部执行时,都会采用三种更具体的join方式来运行.这三种join的

[转贴]Oracle PL/SQL语言基础

oracle|sql语言 [转贴]Oracle PL/SQL语言基础 Oracle PL/SQL语言基础   PL/SQL是ORACLE对标准数据库语言的扩展,ORACLE公司已经将PL/SQL整合到ORACLE 服务器和其他工具中了,近几年中更多的开发人员和DBA开始使用PL/SQL,本文将讲述PL/SQL基础语法,结构和组件.以及如何设计并执行一个PL/SQL程序.    PL/SQL的优点    从版本6开始PL/SQL就被可靠的整合到ORACLE中了,一旦掌握PL/SQL的优点以及其独有

Oracle PL/SQL语言基础

oracle|sql语言 Oracle PL/SQL语言基础  2002-8-23   Oracle PL/SQL语言基础 PL/SQL是ORACLE对标准数据库语言的扩展,ORACLE公司已经将PL/SQL整合到ORACLE 服务器和其他工具中了,近几年中更多的开发人员和DBA开始使用PL/SQL,本文将讲述PL/SQL基础语法,结构和组件.以及如何设计并执行一个PL/SQL程序. PL/SQL的优点 从版本6开始PL/SQL就被可靠的整合到ORACLE中了,一旦掌握PL/SQL的优点以及其独

Oracle常用sql语句

Oracle数据库常用sql语句 ORACLE 常用的SQL语法和数据对象 一.数据控制语句 (DML) 部分 1.INSERT (往数据表里插入记录的语句) INSERT INTO 表名(字段名1, 字段名2, --) VALUES ( 值1, 值2, --); INSERT INTO 表名(字段名1, 字段名2, --) SELECT (字段名1, 字段名2, --) FROM 另外的表名; 字符串类型的字段值必须用单引号括起来, 例如: 'GOOD DAY' 如果字段值里包含单引号' 需要

Oracle\MS SQL Server Update多表关联更新

原文:Oracle\MS SQL Server Update多表关联更新 一条Update更新语句是不能更新多张表的,除非使用触发器隐含更新.而表的更新操作中,在很多情况下需要在表达式中引用要更新的表以外的数据.我们先来讨论根据其他表数据更新你要更新的表   一.MS    SQL    Server   多表关联更新      sql server提供了update的from 子句,可以将要更新的表与其它的数据源连接起来.虽然只能对一个表进行更新,但是通过将要更新的表与其它的数据源连接起来,就

Oracle PL/SQL语言入门基础_oracle

正在看的ORACLE教程是:Oracle PL/SQL语言入门基础.PL/SQL是ORACLE对标准数据库语言的扩展,ORACLE公司已经将PL/SQL整合到ORACLE 服务器和其他工具中了,近几年中更多的开发人员和DBA开始使用PL/SQL,本文将讲述PL/SQL基础语法,结构和组件.以及如何设计并执行一个PL/SQL程序. PL/SQL的优点 从版本6开始PL/SQL就被可靠的整合到ORACLE中了,一旦掌握PL/SQL的优点以及其独有的数据管理的便利性,那么你很难想象ORACLE缺了PL

ORACLE与SQL之间的数据迁移

oracle|数据 高级数据迁移        很多时间,要在异构数据库之间进行数据迁移或抽取,如果在SQL中提取ORACLE的数据,可以通过ODBC.OLEDB等多种方式,要从ORACLE提取SQL中的数据,大都是通过透明网关来实现的.        在异构数据抽取过程中,最好采用SQL92标准的语法编写SQL代码,同时要注意不同数据库之间数据类型的转换关系,如ORACLE的日期类型用DATE.SQL用Datetime等.   一 关于ORACLE的透明网关配置        ORACLE安装

Oracle 高效SQL

oracle No1:选择合适的优化器No2:共享SQL为了不重复解析相同的SQL语句,在第一次解析之后, ORACLE将SQL语句存放在内存中.这块位于系统全局区域SGA(system global area)的共享池(shared buffer pool)中的内存可以被所有的数据库用户共享. 因此,当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同, ORACLE就能很快获得已经被解析的语句以及最好的执行路径. ORACLE的这个功能大大地提高了SQL的执行性

Oracle的sql*plus

oracle Oracle的sql*plus是与oracle进行交互的客户端工具.在sql*plus中,可以运行sql*plus命令与sql*plus语句.    我们通常所说的DML.DDL.DCL语句都是sql*plus语句,它们执行完后,都可以保存在一个被称为sql buffer的内存区域中,并且只能保存一条最近执行的sql语句,我们可以对保存在sql buffer中的sql 语句进行修改,然后再次执行,sql*plus一般都与数据库打交道.    除了sql*plus语句,在sql*pl