1. 程式人生 > 實用技巧 >第13課 建立高階聯結

第13課 建立高階聯結

第13課 建立高階聯結

13.1 使用表別名

給列起別名的語法如下:

SELECT RTRIM(vend_name) + ' (' + RTRIM(vend_country) + ')'
       AS vend_title
FROM Vendors
ORDER BY vend_name;

SQL除了可以對列名和計算欄位使用別名,還允許給表名起別名。這樣做有兩個主要理由:

  • 縮短SQL語句;
  • 允許在一條SELECT語句中多次使用相同的表。
SELECT cust_name, cust_contact
FROM Customers AS C, Orders AS O, OrderItems AS OI
WHERE C.cust_id = O.cust_id
 AND OI.order_num = O.order_num
 AND prod_id = 'RGAN01';

警告:Oracle中沒有AS
Oracle不支援AS關鍵字。要在Oracle中使用別名,可以不用AS,簡單地指定列名即可(因此,應該是Customers C,而不是Customers AS C)。

需要注意,表別名只在查詢執行中使用。與列別名不一樣,表別名不返回到客戶端。

13.2 使用不同型別的聯結

13.2.1 自聯結

使用表別名的一個主要原因是能在一條SELECT語句中不止一次引用相同的表。

SELECT cust_id, cust_name, cust_contact
FROM Customers
WHERE cust_name = (SELECT cust_name
                   FROM Customers
                   WHERE cust_contact = 'Jim Jones');

現在來看使用聯結的相同查詢:

SELECT c1.cust_id, c1.cust_name, c1.cust_contact
FROM Customers AS c1, Customers AS c2
WHERE c1.cust_name = c2.cust_name
 AND c2.cust_contact = 'Jim Jones'; 

13.2.2 自然聯結

標準的聯結(前一課中介紹的內聯結)返回所有資料,相同的列甚至多次出現。自然聯結排除多次出現,使每一列只返回一次。

怎樣完成這項工作呢?答案是,系統不完成這項工作,由你自己完成它。自然聯結要求你只能選擇那些唯一的列,一般通過對一個表使用萬用字元(SELECT *),而對其他表的列使用明確的子集來完成。

SELECT C.*, O.order_num, O.order_date,
       OI.prod_id, OI.quantity, OI.item_price
FROM Customers AS C, Orders AS O, OrderItems AS OI
WHERE C.cust_id = O.cust_id
 AND OI.order_num = O.order_num
 AND prod_id = 'RGAN01';

13.2.3 外聯結

下面的SELECT語句給出了一個簡單的內聯結。它檢索所有顧客及其訂單:

SELECT Customers.cust_id, Orders.order_num
FROM Customers INNER JOIN Orders
 ON Customers.cust_id = Orders.cust_id;

外聯結語法類似。要檢索包括沒有訂單顧客在內的所有顧客,可如下進行:

SELECT Customers.cust_id, Orders.order_num
FROM Customers LEFT OUTER JOIN Orders
 ON Customers.cust_id = Orders.cust_id; 

與內聯結關聯兩個表中的行不同的是,外聯結還包括沒有關聯行的行。在使用OUTER JOIN語法時,必須使用RIGHT或LEFT關鍵字指定包括其所有行的表(RIGHT指出的是OUTER JOIN右邊的表,而LEFT指出的是OUTER JOIN左邊的表)。上面的例子使用LEFT OUTER JOIN從FROM子句左邊的表(Customers表)中選擇所有行。為了從右邊的表中選擇所有行,需要使用RIGHT OUTER JOIN,如下例所示:

SELECT Customers.cust_id, Orders.order_num
FROM Customers RIGHT OUTER JOIN Orders
 ON Orders.cust_id = Customers.cust_id;

13.3 使用帶聚集函式的聯結

SELECT Customers.cust_id,
       COUNT(Orders.order_num) AS num_ord
FROM Customers INNER JOIN Orders
 ON Customers.cust_id = Orders.cust_id
GROUP BY Customers.cust_id;

這條SELECT語句使用INNER JOIN將Customers和Orders表互相關聯。GROUP BY子句按顧客分組資料,因此,函式呼叫COUNT(Orders.order_num)對每個顧客的訂單計數,將它作為num_ord返回。

13.4 使用聯結和聯結條件

彙總一下聯結及其使用的要點。

  • 注意所使用的聯結型別。一般我們使用內聯結,但使用外聯結也有效。
  • 應該總是提供聯結條件,否則會得出笛卡兒積。

13.5 小結

首先講授瞭如何以及為什麼使用別名,然後討論不同的聯結型別以及每類聯結所使用的語法。我們還介紹瞭如何與聯結一起使用聚集函式,以及在使用聯結時應該注意的問題。