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