1. 程式人生 > >Oracle外連線(left/right/full outer join)語法詳解

Oracle外連線(left/right/full outer join)語法詳解

相比常用的精確查詢(內連線,inner join),外連線相比不好理解。但在實際工作中,用的還是很多的,深刻理解外連線成為必須。

看到一篇帖子,清晰易懂,轉發一下。

內容:

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

Oracle  外連線

(1)左外連線 (左邊的表不加限制)
       (2)右外連線(右邊的表不加限制)
       (3)全外連線(左右兩表都不加限制)

     外連線(Outer Join)

outer join則會返回每個滿足第一個(頂端)輸入與第二個(底端)輸入的聯接的行。它還返回任何在第二個輸入中沒有匹配行的第一個輸入中的行。外連線分為三種: 左外連線,右外連線,全外連線。 對應SQL:LEFT/RIGHT/FULL OUTER JOIN。 通常我們省略outer 這個關鍵字。 寫成:LEFT/RIGHT/FULL JOIN。

在左外連線和右外連線時都會以一張表為基表,該表的內容會全部顯示,然後加上兩張表匹配的內容。 如果基表的資料在另一張表沒有記錄。 那麼在相關聯的結果集行中列顯示為空值(NULL)。

對於外連線, 也可以使用“(+) ”來表示。 關於使用(+)的一些注意事項:
       1.(+)操作符只能出現在where子句中,並且不能與outer join語法同時使用。
       2. 當使用(+)操作符執行外連線時,如果在where子句中包含有多個條件,則必須在所有條件中都包含(+)操作符
       3.(+)操作符只適用於列,而不能用在表示式上。
       4.(+)操作符不能與or和in操作符一起使用。
       5.(+)操作符只能用於實現左外連線和右外連線,而不能用於實現完全外連線。


在做實驗之前,我們先將dave表和bl里加一些不同的資料。 以方便測試。

SQL> select * from bl;

        ID NAME

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

         1 dave

         2 bl

         3 big bird

         4 exc

         9 懷寧

SQL> select * from dave;

        ID NAME

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

         8 安慶

         1 dave

         2 bl

         1 bl

         2 dave

         3 dba

         4 sf-express

         5 dmm

2.1 左外連線(Left outer join/ left join)

     left join是以左表的記錄為基礎的,示例中Dave可以看成左表,BL可以看成右表,它的結果集是Dave表中的資料,在加上Dave表和BL表匹配的資料。換句話說,左表(Dave)的記錄將會全部表示出來,而右表(BL)只會顯示符合搜尋條件的記錄。BL表記錄不足的地方均為NULL.

示例:

SQL> select * from dave a left join bl b on a.id = b.id;

       ID NAME               ID NAME

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

        1 bl                  1 dave

        1 dave                1 dave

        2 dave                2 bl

        2 bl                  2 bl

        3 dba                 3 big bird

        4 sf-express          4 exc

        5 dmm                             -- 此處B表為null,因為沒有匹配到

        8 安慶                             -- 此處B表為null,因為沒有匹配到

SQL> select * from dave a left outer join bl b on a.id = b.id;

        ID NAME               ID NAME

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

         1 bl                  1 dave

         1 dave                1 dave

         2 dave                2 bl

         2 bl                  2 bl

         3 dba                 3 big bird

         4 sf-express          4 exc

         5 dmm

         8 安慶

用(+)來實現, 這個+號可以這樣來理解: + 表示補充,即哪個表有加號,這個表就是匹配表。所以加號寫在右表,左表就是全部顯示,故是左連線。

SQL> Select * from dave a,bl b where a.id=b.id(+);    -- 注意: 用(+) 就要用關鍵字where

        ID NAME               ID NAME

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

         1 bl                  1 dave

         1 dave                1 dave

         2 dave                2 bl

         2 bl                  2 bl

         3 dba                 3 big bird

         4 sf-express          4 exc

         5 dmm

         8 安慶

2.2 右外連線(right outer join/ right join)

和left join的結果剛好相反,是以右表(BL)為基礎的, 顯示BL表的所以記錄,在加上Dave和BL 匹配的結果。 Dave表不足的地方用NULL填充.

示例:

SQL> select * from dave a right join bl b on a.id = b.id;

        ID NAME               ID NAME

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

         1 dave                1 dave

         2 bl                  2 bl

         1 bl                  1 dave

         2 dave                2 bl

         3 dba                 3 big bird

         4 sf-express          4 exc

                               9 懷寧    --此處左表不足用Null 填充

已選擇7行。

SQL> select * from dave a right outer join bl b on a.id = b.id;

        ID NAME               ID NAME

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

         1 dave                1 dave

         2 bl                  2 bl

         1 bl                  1 dave

         2 dave                2 bl

         3 dba                 3 big bird

         4 sf-express          4 exc

                               9 懷寧  --此處左表不足用Null 填充

已選擇7行。

用(+)來實現, 這個+號可以這樣來理解: + 表示補充,即哪個表有加號,這個表就是匹配表。所以加號寫在左表,右表就是全部顯示,故是右連線。

SQL> Select * from dave a,bl b where a.id(+)=b.id;

        ID NAME               ID NAME

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

         1 dave                1 dave

         2 bl                  2 bl

         1 bl                  1 dave

         2 dave                2 bl

         3 dba                 3 big bird

         4 sf-express          4 exc

                               9 懷寧

2.3 全外連線(full outer join/ full join)

     左表和右表都不做限制,所有的記錄都顯示,兩表不足的地方用null 填充。 全外連線不支援(+)這種寫法。

示例:

SQL> select * from dave a full join bl b on a.id = b.id;

        ID NAME               ID NAME

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

         8 安慶

         1 dave                1 dave

         2 bl                  2 bl

         1 bl                  1 dave

         2 dave                2 bl

         3 dba                 3 big bird

         4 sf-express          4 exc

         5 dmm

                               9 懷寧

已選擇9行。

SQL> select * from dave a full outer join bl b on a.id = b.id;

        ID NAME               ID NAME

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

         8 安慶

         1 dave                1 dave

         2 bl                  2 bl

         1 bl                  1 dave

         2 dave                2 bl

         3 dba                 3 big bird

         4 sf-express          4 exc

         5 dmm     

Oracle Database SQL Language Reference中關於outer join的描述:

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

Outer Joins
An outer join extends the result of a simple join. An outer join returns all rows that satisfy the join condition and also returns some or all of those rows from one table for
which no rows from the other satisfy the join condition.
■ To write a query that performs an outer join of tables A and B and returns all rows from A (a left outer join), use the LEFT [OUTER] JOIN syntax in the FROM clause, or
apply the outer join operator (+) to all columns of B in the join condition in the WHERE clause. For all rows in A that have no matching rows in B, Oracle Database
returns null for any select list expressions containing columns of B.
■ To write a query that performs an outer join of tables A and B and returns all rows from B (a right outer join), use the RIGHT [OUTER] JOIN syntax in the FROM clause, or
apply the outer join operator (+) to all columns of A in the join condition in the WHERE clause. For all rows in B that have no matching rows in A, Oracle returns
null for any select list expressions containing columns of A.
■ To write a query that performs an outer join and returns all rows from A and B, extended with nulls if they do not satisfy the join condition (a full outer join), use
the FULL [OUTER] JOIN syntax in the FROM clause.
You cannot compare a column with a subquery in the WHERE clause of any outer join, regardless which form you specify.
You can use outer joins to fill gaps in sparse data. Such a join is called a partitioned
outer join and is formed using the query_partition_clause of the join_clause syntax. Sparse data is data that does not have rows for all possible values of a dimension such as time or department. For example, tables of sales data typically do not have rows for products that had no sales on a given date. Filling data gaps is useful in situations where data sparsity complicates analytic computation or where some data might be missed if the sparse data is queried directly.

Oracle recommends that you use the FROM clause OUTER JOIN syntax rather than the Oracle join operator. Outer join queries that use the Oracle join operator (+) are subject to the following rules and restrictions, which do not apply to the FROM clause OUTER JOIN syntax:
■ You cannot specify the (+) operator in a query block that also contains FROM clause join syntax.
■ The (+) operator can appear only in the WHERE clause or, in the context of left-correlation (when specifying the TABLE clause) in the FROM clause, and can be applied only to a column of a table or view.
■ If A and B are joined by multiple join conditions, then you must use the (+) operator in all of these conditions. If you do not, then Oracle Database will return only the rows resulting from a simple join, but without a warning or error to advise you that you do not have the results of an outer join.
■ The (+) operator does not produce an outer join if you specify one table in the outer query and the other table in an inner query.
■ You cannot use the (+) operator to outer-join a table to itself, although self joins are valid. For example, the following statement is not valid:
-- The following statement is not valid:
SELECT employee_id, manager_id
FROM employees
WHERE employees.manager_id(+) = employees.employee_id;
However, the following self join is valid:
SELECT e1.employee_id, e1.manager_id, e2.employee_id
FROM employees e1, employees e2
WHERE e1.manager_id(+) = e2.employee_id
ORDER BY e1.employee_id, e1.manager_id, e2.employee_id;
■ The (+) operator can be applied only to a column, not to an arbitrary expression.
However, an arbitrary expression can contain one or more columns marked with the (+) operator.
■ A WHERE condition containing the (+) operator cannot be combined with another condition using the OR logical operator.
■ A WHERE condition cannot use the IN comparison condition to compare a column marked with the (+) operator with an expression.
If the WHERE clause contains a condition that compares a column from table B with a constant, then the (+) operator must be applied to the column so that Oracle returns
the rows from table A for which it has generated nulls for this column. Otherwise Oracle returns only the results of a simple join.
In a query that performs outer joins of more than two pairs of tables, a single table can be the null-generated table for only one other table. For this reason, you cannot apply
the (+) operator to columns of B in the join condition for A and B and the join condition for B and C. Refer to SELECT on page 19-4 for the syntax for an outer join.