oracle join

-- http://www.cnblogs.com/kerrycode/p/5935704.html
-- http://www.cnblogs.com/hehaiyang/p/4745897.html  参考

我们先准备一个两个测试表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> 
clip_image002
 
注意,INNER JOIN可以用使用简写JOIN方式,如下所示,但是建议使用INNER JOIN 而不是JOIN这样的语法。
 
clip_image003
 
如果我们用韦恩图来解释INNER JOIN,则非常一目了然、形象生动。
可以用下面图来表示(此图以及下面的韦恩图均来自链接http://pafumi.net/SQL_Joins.html ,
本来想自己画,无奈有些图使用word不好实现,R语言不会。故在此借其图用用)
 
clip_image004
 
 
-- 外连接: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.
clip_image005
 
FULL OUTER JOIN的韦恩图如下所示:
 
clip_image006
 
 
-- 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> 
clip_image007
 
LEFT OUTER JOIN的韦恩图如下所示:
clip_image008
 
 
-- 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
clip_image009
 
 
-- 笛卡尔积:CROSS JOIN
 
CROSS JOIN就是笛卡尔乘积连接,不需要任何关联条件,实现M*N的结果集,
其实这种SQL JOIN方式基本上只在理论上有意义,实际当中,很少有用的CORSS JOIN方式。
注意: cross join跟inner joinouter 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.
clip_image010
注意:笛卡尔积用维恩图是无法体现出来的。
 
-- 自然连接: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> 
clip_image011
 
自然连接的两个表的有多个字段都满足有相同名称,那么他们会被作为自然连接的条件,如下案例所示
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
clip_image012
 
NATURAL JOIN的韦恩图,其实和内连接是一样的。如下所示:

 

posted on 2017-08-20 20:14  程序员修仙之路  阅读(254)  评论(0编辑  收藏  举报