1 使用別名
SELECT CONCAT(vend_name,'(',vend_country,')') AS vend_title FROM vendors ORDER BY vend_name;
SQL除了可以對(duì)列名和計(jì)算字段使用別名,還允許給表名起別名。這樣做有兩個(gè)主要理由:
- 縮短SQL語(yǔ)句;
- 允許在一條SELECT語(yǔ)句中多次使用相同的表。
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'
as.png
表別名不僅能用于WHERE子句,還可以用于SELECT的列表、ORDER BY子句以及其他語(yǔ)句部分。
注意:Oracle不支持AS關(guān)鍵字,直接指定別名即可。(例如:orders O)
2 使用不同類型的聯(lián)結(jié)
除了內(nèi)聯(lián)結(jié)(inner join)之外,現(xiàn)在來(lái)看三種其他聯(lián)結(jié):自聯(lián)結(jié)(self-join)、自然聯(lián)結(jié)(natural join)和外聯(lián)結(jié)(outer join)。
2.1 自聯(lián)結(jié)
使用子查詢:
SELECT cust_id,cust_name,cust_contact FROM customers WHERE cust_name = (SELECT cust_name FROM customers WHERE cust_contact = 'Jim Jones');
使用聯(lián)結(jié)的相同查詢:
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'

提示:使用自聯(lián)結(jié)而不用子查詢
DBMS處理聯(lián)結(jié)遠(yuǎn)比處理子查詢快得多。
2.2 自然聯(lián)結(jié)
標(biāo)準(zhǔn)的聯(lián)結(jié)(內(nèi)聯(lián)結(jié))返回所有數(shù)據(jù),相同的列甚至多次出現(xiàn)。自然聯(lián)結(jié)排除多次出現(xiàn),使每一列只返回一次。系統(tǒng)不會(huì)完成這項(xiàng)工作,只能自己完成。
自然聯(lián)結(jié)要求只能選擇那些唯一的列,一般通過對(duì)一個(gè)表使用通配符(SELECT *),而對(duì)其他表的列使用明確的子集來(lái)完成。
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';

事實(shí)上,我們迄今為止建立的每個(gè)內(nèi)聯(lián)結(jié)都是自然聯(lián)結(jié),很可能永遠(yuǎn)都不會(huì)用到不是自然聯(lián)結(jié)的內(nèi)聯(lián)結(jié)。
2.3 外聯(lián)結(jié)
聯(lián)結(jié)包含了那些在相關(guān)表中沒有關(guān)聯(lián)行的行。這種聯(lián)結(jié)稱為外聯(lián)結(jié)。
先看一個(gè)簡(jiǎn)單的內(nèi)聯(lián)結(jié):
SELECT customers.cust_id, orders.order_num FROM customers INNER JOIN orders ON customers.cust_id = orders.cust_id;

外聯(lián)結(jié)語(yǔ)法類似:檢索包括沒有訂單顧客在內(nèi)的所有顧客。
SELECT customers.cust_id,orders.order_num FROM customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id ;

與內(nèi)聯(lián)結(jié)關(guān)聯(lián)兩個(gè)表中的行不同的是,外聯(lián)結(jié)還包括沒有關(guān)聯(lián)行的行。
在使用OUTER JOIN語(yǔ)法時(shí),必須使用RIGHT或LEFT關(guān)鍵字指定包括其所有行的表(RIGHT指出的是OUTER JOIN右邊的表,而LEFT指出的是OUTER JOIN左邊的表)。
SELECT customers.cust_id,orders.order_num FROM customers RIGHT OUTER JOIN orders ON customers.cust_id = orders.cust_id ;

提示:外聯(lián)結(jié)的類型
要記住,總是有兩種基本的外聯(lián)結(jié)形式:左外聯(lián)結(jié)和右外聯(lián)結(jié)。它們之間的唯一差別是所關(guān)聯(lián)的表的順序。換句話說,調(diào)整FROM或WHERE子句中表的順序,左外聯(lián)結(jié)可以轉(zhuǎn)換為右外聯(lián)結(jié)。因此,這兩種外聯(lián)結(jié)可以相互使用。
還存在另一種外聯(lián)結(jié),就是全外聯(lián)結(jié)(full outer join),它檢索兩個(gè)表中的所有行并關(guān)聯(lián)那些可以關(guān)聯(lián)的行。與左外聯(lián)結(jié)或右外聯(lián)結(jié)包含一個(gè)表的不關(guān)聯(lián)的行不同,全外聯(lián)結(jié)包含兩個(gè)表的不關(guān)聯(lián)的行。
然而MySQL不支持這個(gè)語(yǔ)法,但是可以通過union來(lái)實(shí)現(xiàn) :
SELECT customers.cust_id,orders.order_num FROM customers LEFT OUTER JOIN orders ON customers.cust_id = orders.cust_id UNION SELECT customers.cust_id,orders.order_num FROM customers RIGHT OUTER JOIN orders ON customers.cust_id = orders.cust_id ;

3 使用帶聚集函數(shù)的聯(lián)結(jié)

例子:檢索所有顧客及每個(gè)顧客所下的訂單數(shù)。
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;

例子:使用左外聯(lián)結(jié)檢索包含所有顧客及其對(duì)應(yīng)的訂單數(shù)(包含沒有任何訂單的顧客)
SELECT c.cust_id,COUNT(o.order_num) AS num_ord FROM customers c LEFT OUTER JOIN orders o ON c.cust_id = o.cust_id GROUP BY c.cust_id;

4 總結(jié)
- 注意所使用的聯(lián)結(jié)類型。一般我們使用內(nèi)聯(lián)結(jié),但使用外聯(lián)結(jié)也有效。
- 注意使用正確的聯(lián)結(jié)語(yǔ)法。
- 保證使用正確的聯(lián)結(jié)條件。
- 必須給出聯(lián)結(jié)條件,避免出現(xiàn)笛卡爾積。
- 在一個(gè)聯(lián)結(jié)中可以包含多個(gè)表,甚至可以對(duì)每個(gè)聯(lián)結(jié)采用不同的聯(lián)結(jié)類型。雖然這樣做是合法的,一般也很有用,但是應(yīng)該在一起測(cè)試它們前分別測(cè)試每個(gè)聯(lián)結(jié)。
