Oracle學習筆記(四):多表查詢(二)

外連接(OUTER JOIN) , 交叉連接(CROSS JOIN),和三個操作符(UNION , INTERSECT , MINUS)

外連接(OUTER JOIN)

我們將建立兩個表,說明下面sql語句的使用原理

A表:

B表:


CREATE TABLE A(                 --A表
  id NUMBER(2) ,
  Aname VARCHAR2(5) 
) ;

CREATE TABLE B(               --B表
  id NUMBER(2) ,
  Bname VARCHAR2(5)
) ;

這兩個表中有一些id相同,有一些不同。

我們INSERT:

INSERT INTO a VALUES(1,'A01') ;
INSERT INTO a VALUES(6,'A06') ;
INSERT INTO a VALUES(7,'A07') ;
INSERT INTO a VALUES(8,'A08') ;
INSERT INTO a VALUES(12,'A12') ;
INSERT INTO a VALUES(13,'A13') ;
INSERT INTO a VALUES(14,'A14') ;

INSERT INTO B VALUES(2,'B02') ;
INSERT INTO B VALUES(3,'B03') ;
INSERT INTO B VALUES(4,'B04') ;
INSERT INTO B VALUES(5,'B05') ;
INSERT INTO B VALUES(6,'B06') ;
INSERT INTO B VALUES(7,'B07') ;
INSERT INTO B VALUES(8,'B08') ;
對於外連接,Oracle中可以使用(+)來表示,也可以使用LEFT,RIGHT和FULL OUTER JOIN實現多個表外連接

外連接分爲3類
1,左外連接(LEFT OUTER JOIN或LEFT JOIN)
2,右外連接(RIGHT OUTER JOIN或RIGHT JOIN)
3,全外連接(FULL OUTER JOIN或FULL JOIN)
使用外連接,可以列出與連接條件相匹配的行,並且列出左表(左外連接時),右表(右外連接時)或兩個表(全外連接時),所有符合檢索條件的數據行

1,左外連接:

SQL> SELECT a.id , a.aname , b.id , b.bname
  2  FROM a LEFT OUTER JOIN b
  3  ON a.id = b.id ;

        ID ANAME         ID BNAME
---------- ----- ---------- -----
         6 A06            6 B06
         7 A07            7 B07
         8 A08            8 B08
        13 A13
        12 A12
         1 A01
        14 A14

已選擇7行。

~注:從定義的A表B表看來,只有id=6,7,8時兩個表的ID纔會相同,而left outer join會把左表,也就是a表與條件不匹配的也輸出來。而對於INNER JOIN ,我們可以對比一下效果:

SQL> SELECT a.id , a.aname , b.id , b.bname
  2  FROM a INNER JOIN b
  3  ON a.id = b.id ;

        ID ANAME         ID BNAME
---------- ----- ---------- -----
         6 A06            6 B06
         7 A07            7 B07
         8 A08            8 B08

實際上外連接也可以這樣來寫:

SQL> SELECT a.id , a.aname , b.id , b.bname
  2  FROM a INNER JOIN b
  3  ON a.id = b.id(+) ;

        ID ANAME         ID BNAME
---------- ----- ---------- -----
         6 A06            6 B06
         7 A07            7 B07
         8 A08            8 B08
        13 A13
        12 A12
         1 A01
        14 A14

已選擇7行。

與前面效果一樣。注意:這裏的(+)要與連接的方向相反。

因此,我們可以把外連接看成是內連接加上左表(當外連接爲左時),右表(當外連接爲右時)沒匹配的數據。

2,右外連接(與左連接類似,只是方向變了)

3,全外連接

這個其實也只是左連接與右連接的綜合,比較好理解。

SQL> SELECT a.id , a.aname , b.id , b.bname
  2  FROM a FULL OUTER JOIN b
  3  ON a.id = b.id ;

        ID ANAME         ID BNAME
---------- ----- ---------- -----
                          2 B02
                          3 B03
                          4 B04
                          5 B05
         6 A06            6 B06
         7 A07            7 B07
         8 A08            8 B08
        13 A13
        12 A12
         1 A01
        14 A14

已選擇11行。

~注:從上面我們可以看出,相同id的兩個表都同時在,而id不同的則輸出空的值。


交叉連接

除此之外,外連接還有CROSS JOIN,也就是交叉連接,所得到的結果將是這兩個表中各行數據的所有組合,即這個表所有數據行的笛卡爾積。

交叉連接與簡單連接非常相似,不同的是,使用交叉連接時,在FROM字句中多個表名之間使用的不是逗號,而是使用CROSS JOIN隔開,而且不需要用ON指定條件,但可以在WHERE中添加。

SQL> SELECT a.id , a.aname , b.id , b.bname
  2  FROM a CROSS JOIN b
  3  WHERE a.id = b.id ;

        ID ANAME         ID BNAME
---------- ----- ---------- -----
         6 A06            6 B06
         7 A07            7 B07
         8 A08            8 B08
當沒有WHERE條件時,將返回:


~注:從上面看,我們發現,交叉連接與之前的簡單連接差不多,若沒有where語句限制,也會產生笛卡爾積。


UNION , INTERSECT , MINUS操作符

我們繼續拿SCOTT的emp表作爲例子:

選取empno>7800的員工信息作爲集合A,部門號爲10的員工信息作爲集合B

集合A:

SQL> SELECT empno , ename , sal ,deptno
  2  FROM emp
  3  WHERE empno > 7800 ;

     EMPNO ENAME             SAL     DEPTNO
---------- ---------- ---------- ----------
      7839 KING             5000         10
      7844 TURNER           1500         30
      7876 ADAMS            1100         20
      7900 JAMES             950         30
      7902 FORD             3000         20
      7934 MILLER           1300         10

已選擇6行。

集合B:

SQL> SELECT empno , ename , sal ,deptno
  2  FROM emp
  3  WHERE deptno = 10 ;

     EMPNO ENAME             SAL     DEPTNO
---------- ---------- ---------- ----------
      7782 CLARK            2450         10
      7839 KING             5000         10
      7934 MILLER           1300         10
直接看我們知道empno=7839與7934時A和B是相同的


下面我們分類進行解釋與試驗:

SQL語言中的MINUS集合運算,表示獲得給定集合之間的差異,也就意味着所得到的結果集中,其中的元素僅存在於前一個集合中,而不存在於另一集合中

如圖所示:

SQL> SELECT empno , ename , sal ,deptno
  2  FROM emp
  3  WHERE empno > 7800
  4  MINUS
  5  SELECT empno , ename , sal ,deptno
  6  FROM emp
  7  WHERE deptno = 10 ;

     EMPNO ENAME             SAL     DEPTNO
---------- ---------- ---------- ----------
      7844 TURNER           1500         30
      7876 ADAMS            1100         20
      7900 JAMES             950         30
      7902 FORD             3000         20


INTERSECT獲取公共行,也稱爲獲取結果集的交集

如圖所示:

SQL> SELECT empno , ename , sal ,deptno
  2  FROM emp
  3  WHERE empno > 7800
  4  INTERSECT
  5  SELECT empno , ename , sal ,deptno
  6  FROM emp
  7  WHERE deptno = 10 ;

     EMPNO ENAME             SAL     DEPTNO
---------- ---------- ---------- ----------
      7839 KING             5000         10
      7934 MILLER           1300         10


UNION返回多個查詢返回的行組合起來:

SQL> SELECT empno , ename , sal ,deptno
  2  FROM emp
  3  WHERE empno > 7800
  4  UNION
  5  SELECT empno , ename , sal ,deptno
  6  FROM emp
  7  WHERE deptno = 10 ;

     EMPNO ENAME             SAL     DEPTNO
---------- ---------- ---------- ----------
      7782 CLARK            2450         10
      7839 KING             5000         10
      7844 TURNER           1500         30
      7876 ADAMS            1100         20
      7900 JAMES             950         30
      7902 FORD             3000         20
      7934 MILLER           1300         10
~注:從上面我們看出,這三個運算符,只是在兩個SELECT語句中直接插入UNION,MINUS,INTERSECT三個之一。學過集合論的人對這些都不難理解。我們把每次SELECT得到的結果看成是一個集合,那麼三面的SQL語句我們就可以把它看成是集合間的運算了。


~綜:綜合這兩篇博客所學到的東西,我看到了Oracle多表連接查詢有很多看上去非常複雜的東西,比如INNER JOIN,OUTER JOIN ,CROSS JOIN等等這些,而當我逐步弄清楚後,就會發現這些其實只是多表查詢的基礎的一些遷移,原理還是一樣,只要理解了多表查詢的思想,就可以很容易理解外連接,內連接這些東西了。但我覺得這也只是基礎。學會了很多SQL的東西,卻不一定可以寫出好的SQL語句,甚至有些SQL語句也寫不出。學習是個積累的過程,對於博大精深的Oralce更是,千萬不能讓一時的收穫矇蔽了自己,自己還需花更多的時間去學習。繼續加油!




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章