天天看點

第六十章 SQL指令 JOIN(二)

文章目錄

  • 第六十章 SQL指令 JOIN(二)
  • 單向外部聯接
    • 外部聯接文法
    • Null填充
  • 混合外部和内部連接配接
    • 多重連接配接和隐式連接配接的性能
  • 示例
    • CROSS JOIN 示例
    • NATURAL JOIN 示例
    • 使用ON子句的INNER JOIN示例
    • 使用USING子句的INNER JOIN示例
    • LEFT OUTER JOIN 示例
    • RIGHT OUTER JOIN 示例
    • FULL OUTER JOIN

單向外部聯接

IRIS支援單向外部聯接:左外部聯接和右外部聯接。

使用标準的

“inner”

聯接時,當一個表的行連結到第二個表的行時,第一個表中找不到第二個表中對應行的行将從輸出表中排除。

使用單向外聯接時,即使第二個表中沒有比對項,第一個表中的所有行也會包括在輸出表中。使用單向外連接配接,第一個表會從第二個表中取出相關資訊,但不會因為第二個表中缺少比對項而犧牲自己的行。

例如,如果查詢首先列出

Table1

并建立一個左外部聯接,那麼它應該能夠看到

Table1

中的所有行,即使它們在

Table2

中沒有對應的記錄。

在指定單向外聯接時,在

FROM

子句中命名表的順序非常重要。對于左外部聯接,指定的第一個表是聯接的源表。對于右外部聯接,指定的第二個表是聯接的源表。是以,

%INORDER

%STARTTABLE

優化關鍵字不能與

RIGHT OUTER JOIN

一起使用。以下文法互相沖突,導緻

SQLCODE-34

錯誤:

FROM%INORDER TABLE1 RIGHT OUTER JOIN TABLE2 ON....

IRIS支援兩種表示外連接配接的格式:

  1. ANSI

    标準文法:

    LEFT OUTER JOIN

    RIGHT OUTER JOIN

    。SQL标準文法将外聯接放在

    SELECT

    語句的

    FROM

    子句中,而不是

    WHERE

    子句中,如下例所示:
FROM tbl1 LEFT OUTER JOIN tbl2 ON (tbl1.key = tbl2.key) 
           
  1. ODBC規範外部聯接擴充文法,使用轉義文法

    {OJ Join-Expression}

    ,其中

    Join-Expression

    是任何ANSI标準聯接文法。

單向外聯接執行空值填充。這意味着,如果源表的某一行的合并列具有空值,則會為非源表中的相應字段傳回空值。

左外部聯接條件由以下文法表示:

A LEFT OUTER JOIN B ON A.x=B.y
           

這指定傳回

A

中的每一行。對于傳回的每個

A

行,如果有一個

B

行使得

A.x=B.Y

,則還将傳回所有相應的B值。

如果沒有

A.x=B.y

B

行,則填充空值會導緻該

A

行的所有

B

值傳回為空值。

例如,考慮包含患者資訊的

Patient

表,其中包括一個字段

Patient

指定患者主治醫生的

DocID

ID

代碼。

資料庫中的一些患者沒有主診醫生,是以對這些患者記錄“患者”。

DocID

字段為

NULL

現在,我們在

Patient

表和

Doctor

表之間執行連接配接,以生成一個包含患者姓名和相應醫生姓名的表。

SELECT Patient.PName,Doctor.DName
   FROM Patient INNER JOIN Doctor
   ON Patient.DocID=Doctor.DocID
           

INNER JOIN

不執行空填充。

是以,如果沒有相應的醫生姓名,則不會傳回患者姓名。

單向外聯接确實執行空值填充。是以,沒有相應醫生名稱的患者名稱将為

Doctor.DName

傳回

NULL

SELECT Patient.PName,Doctor.DName
   FROM Patient LEFT OUTER JOIN Doctor
   ON Patient.DocID=Doctor.DocID
           

單向外聯接條件(包括必要的空值填充)在其他條件之前應用。是以,

WHERE

子句中不能由填充空值的值滿足的條件(例如,

B

中字段的範圍或相等條件)有效地将

A

B

的單向外聯接轉換為正常聯接(内聯接)。

例如,如果将子句

“WHERE Doctor.Age < 45”

添加到上面的兩個

“Patient”

表查詢中,則它們是等效的。但是,如果添加子句

“WHERE Doctor.Age < 45 OR Doctor.Age is null”

,它将保留這兩個查詢之間的差異。

混合外部和内部連接配接

IRIS支援任意順序的混合内部連接配接和外部連接配接的所有文法。

預設情況下,查詢優化器将多個連接配接操作按其對最優序列的最佳估計排序。

這不一定是在查詢中指定的連接配接順序。

可以在

FROM

子句中指定

%INORDER

%FIRSTTABLE

%STARTTABLE

查詢優化選項,以顯式指定表連接配接的順序。

查詢優化器可以執行子查詢扁平化,将某些子查詢轉換為顯式連接配接。

當子查詢數量較少時,這将極大地提高連接配接性能。

當子查詢的數量超過一個或兩個時,子查詢扁平化在某些情況下可能會略微降低性能。

FROM

%NOFLATTEN

查詢優化選項,以顯式指定不應該執行子查詢扁平化。

隻有當子查詢扁平化後,查詢中的連接配接總數不超過

15

個連接配接時,查詢優化器才會執行子查詢扁平化。

指定超過

15

個聯接,如果其中一些聯接是隐式聯接或聯接子查詢,則會導緻查詢性能的顯著下降。

示例

下面的示例顯示了在表1和表2上執行

JOIN

操作的結果。

Table1

Column1 Column2
aaa bbb
ccc
xxx yyy
hhh zzz
Column3
ggg

SELECT * FROM Table1 CROSS JOIN Table2
           

SELECT * FROM Table1 NATURAL JOIN Table2
           

SELECT * FROM Table1 INNER JOIN Table2
     ON Table1.Column1=Table2.Column3
           

SELECT * FROM Table1 INNER JOIN Table2
  USING (Column1)
           

SELECT * FROM Table1 LEFT OUTER JOIN Table2
  ON Table1.Column1=Table2.Column3
           
null

SELECT * FROM Table1 RIGHT OUTER JOIN Table2
     ON Table1.Column1=Table2.Column3
           

SELECT * FROM Table1 FULL OUTER JOIN Table2
  ON Table1.Column1=Table2.Column3