一、聯接( join)
通過聯接,可以根據各個表之間的邏輯關系從兩個或多個表中檢索數據。聯接表示應如何使用一個表中的數據來選擇另一個表中的行。
聯接條件通過以下方法定義兩個表在查詢中的關聯方式:
指定每個表中要用於聯接的列。典型的聯接條件在一個表中指定外鍵,在另一個表中指定與其關聯的鍵。指定比較各列的值時要使用的邏輯運算符(=、<> 等)。
二、聯接類型
當聯接表時,創建的聯接類型影響出現在結果集內的行。聯接類型:
三、內聯接
內連接也叫自然連接,它是組合兩個表的常用方法。自然連接將兩個表中的列進行比較,將兩個表中滿足連接條件的行組合起來,作為結果。自然連接有兩種形式的語法。
語法一:
SELECT 列 FROM 表1 [insert] JION 表2 ON 表1.列=表2.列
語法二:
SELECT 列 FROM 表1,表2 WHERE表1.列=表2.列
【例】從titles、authors和titleauthor表中查詢書的書號、書名、作者號和作者名。
select titles.title_id, title, authors.au_id, au_lname from titles join titleauthor on titles.title_id=titleauthor.title_id join authors on authors.au_id=titleauthor.au_id
四、外連接(Outer join)
在自然連接中,只有在兩個表中匹配的行才能在結果集中出現。而在外連接中可以只限制一個表,而對另外一個表不加限制(即所有的行都出現在結果集中)。
外連接分為左外連接、右外連接和全外連接。左外連接是對連接條件中左邊的表不加限制;右外連接是對右邊的表不加限制;全外連接對兩個表都不加限制,所有兩個表中的行都會包括在結果集中。
五、外連接(Outer join)語法
左外連接的語法為: SELECT 列 FROM 表1 LEFT [OUTER]JOIN 表2 ON 表1.列1=表2.列2
右外連接的語法為: SELECT select_list FROM 表1 RIGHT[OUTER]JOIN 表2 ON 表1.列1=表2.列2
全外連接(完整外部聯接)的語法為: SELECT select_list FROM 表1 FULL[OUTER] JOIN 表2 ON 表1.列1=表2.列2
六、左向外聯接
包括第一個命名表(“左”表,出現在 JOIN 子句的最左邊)中的所有行。不包括右表中的不匹配行。
【例35】下面的 SQL 語句說明 titles 表和 publishers 表之間的左向外聯接包括所有的書名,甚至包括那些沒有出版商信息的書名: Use pubs SELECT titles.title_id, titles.title, publishers.pub_name FROM titles LEFT OUTER JOIN publishers ON titles.pub_id = publishers.pub_id
七、右向外聯接
包括第二個命名表(“右”表,出現在 JOIN 子句的最右邊)中的所有行。不包括左表中的不匹配行。
【例36】在 titles 和 publishers 表之間的右向外聯接將包括所有的出版商,甚至包括那些在 titles 表中沒有書名的出版商。
SELECT titles.title_id, titles.title, publishers.pub_name FROM titles RIGHT OUTER JOIN publishers ON titles.pub_id = publishers.pub_id
八、完整外部聯接
包括所有聯接表中的所有行,不論它們是否匹配。
【例37】 titles 表和 publishers 表之間的完整外部聯接顯示所有書名和所有出版商,甚至包括那些在另一個表中沒有匹配值的書名和出版商。
SELECT titles.title_id, titles.title, publishers.pub_name FROM titles FULL OUTER JOIN publishers ON titles.pub_id = publishers.pub_id
九、交叉聯接
沒有 WHERE 子句的交叉聯接將產生聯接所涉及的表的笛卡爾積。第一個表的行數乘以第二個表的行數等於笛卡爾積結果集的大小。
【例39】 閱讀以下程序:
USE pubs
SELECT au_fname, au_lname, pub_name FROM authors CROSS JOIN publishers ORDER BY au_lname DESC
說明:結果集包含 184 行(authors 有 23 行,publishers 有 8 行;23 乘以 8 等於 184)。 不過,如果添加一個 WHERE 子句,則交叉聯接的作用將同內聯接一樣。
之前我們看到的左連接 (left join),又稱內部連接 (inner join)。在這個情況下,要兩個表格內都有同樣的值,那一筆資料才會被選出。那如果我們想要列出一個表格中每一筆的資料,無論它的值在另一個表格中有沒有出現,那該怎麼辦呢?在這個時候,我們就需要用到 SQL OUTER JOIN (外部連接) 的指令。
外部連接的語法是依數據庫教程的不同而有所不同的。舉例來說,在 Oracle 上,我們會在 WHERE 子句中要選出所有資料的那個表格之後加上一個 "(+)" 來代表說這個表格中的所有資料我們都要。
假設我們有以下的兩個表格:
Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999
Geography 表格 region_name store_name
East Boston
East New York
West Los Angeles
West San Diego
我們需要知道每一間店的營業額。如果我們用一個普通的連接,我們將會漏失掉 'New York'這個店,因為它並不存在於 Store_Information 這個表格。所以,在這個情況下,我們需要用外部連接來串聯這兩個表格:
SELECT A1.store_name, SUM(A2.Sales) SALES
FROM Georgraphy A1, Store_Information A2
WHERE A1.store_name = A2.store_name (+)
GROUP BY A1.store_name
我們在這裡是使用了 Oracle 的外部連接語法。
結果:
store_name SALES
Boston $700
New York
Los Angeles $1800
San Diego $250
請注意: 當第二個表格沒有相對的資料時,SQL 會傳回 NULL 值。在這一個例子中, 'New York' 並不存在於 Store_Information 表格,所以它的 "SALES" 欄位是 NULL。
sql union
UNION 指令的目的是將兩個 SQL 語句的結果合並起來。從這個角度來看, UNION 跟 JOIN 有些許類似,因為這兩個指令都可以由多個表格中撷取資料。 UNION 的一個限制是兩個 SQL 語句所產生的欄位需要是同樣的資料種類。另外,當我們用 UNION這個指令時,我們只會看到不同的資料值 (類似 SELECT DISTINCT)。
UNION 的語法如下:
[SQL 語句 1]
UNION
[SQL 語句 2]
假設我們有以下的兩個表格,
Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999
Internet Sales 表格 Date Sales
Jan-07-1999 $250
Jan-10-1999 $535
Jan-11-1999 $320
Jan-12-1999 $750
而我們要找出來所有有營業額 (sales) 的日子。要達到這個目的,我們用以下的 SQL 語句:
SELECT Date FROM Store_Information
UNION
SELECT Date FROM Internet_Sales
結果:
Date
Jan-05-1999
Jan-07-1999
Jan-08-1999
Jan-10-1999
Jan-11-1999
Jan-12-1999
有一點值得注意的是,如果我們在任何一個 SQL 語句 (或是兩句都一起) 用 "SELECT DISTINCT Date" 的話,那我們會得到完全一樣的結果。
UNION ALL 這個指令的目的也是要將兩個 SQL 語句的結果合並在一起。 UNION ALL 和 UNION 不同之處在於 UNION ALL 會將每一筆符合條件的資料都列出來,無論資料值有無重復。
UNION ALL 的語法如下:
[SQL 語句 1]
UNION ALL
[SQL 語句 2]
我們用和上一頁同樣的例子來顯示出 UNION ALL 和 UNION 的不同。同樣假設我們有以下兩個表格,
Store_Information 表格
store_name Sales Date
Los Angeles $1500 Jan-05-1999
San Diego $250 Jan-07-1999
Los Angeles $300 Jan-08-1999
Boston $700 Jan-08-1999
Internet Sales 表格 Date Sales
Jan-07-1999 $250
Jan-10-1999 $535
Jan-11-1999 $320
Jan-12-1999 $750
而我們要找出有店面營業額以及網絡營業額的日子。要達到這個目的,我們用以下的 SQL 語句:
SELECT Date FROM Store_Information
UNION ALL
SELECT Date FROM Internet_Sales
結果:
Date
Jan-05-1999
Jan-07-1999
Jan-08-1999
Jan-08-1999
Jan-07-1999
Jan-10-1999
Jan-11-1999
Jan-12-1999