使用表別名 使用別名引用被檢索的表列 別名除了用於列名和計算欄位外,SQL還允許給表名起別名。這樣做 有兩個主要理由: + 縮短SQL語句; + 允許在單條 SELECT 語句中多次使用相同的表。 可以看到, FROM 子句中3個表全都具有別名。 customers AS c 建立 c 作為 cus ...
使用表別名
使用別名引用被檢索的表列
別名除了用於列名和計算欄位外,SQL還允許給表名起別名。這樣做
有兩個主要理由:
- 縮短SQL語句;
- 允許在單條 SELECT 語句中多次使用相同的表。
可以看到, FROM 子句中3個表全都具有別名。 customers AS c
建立 c 作為 customers 的別名,等等。這使得能使用省寫的 c 而
不是全名 customers 。在此例子中,表別名只用於 WHERE 子句。但是,表
別名不僅能用於 WHERE 子句,它還可以用於 SELECT 的列表、 ORDER BY 子句
以及語句的其他部分。
應該註意,表別名只在查詢執行中使用。與列別名不一樣,表別名
不返回到客戶機
使用不同類型的聯結
迄今為止,我們使用的只是稱為內部聯結或等值聯結(equijoin)的簡
單聯結。現在來看3種其他聯結,它們分別是自聯結、自然聯結和外部聯結
自聯結
如前所述,使用表別名的主要原因之一是能在單條 SELECT 語句中不
止一次引用相同的表。下麵舉一個例子
假如你發現某物品(其ID為 DTNTR )存在問題,因此想知道生產該物
品的供應商生產的其他物品是否也存在這些問題。此查詢要求首先找到
生產ID為 DTNTR 的物品的供應商,然後找出這個供應商生產的其他物品。
下麵是解決此問題的一種方法
這是第一種解決方案,它使用了子查詢。內部的 SELECT 語句做
了一個簡單的檢索,返回生產ID為 DTNTR 的物品供應商的
vend_id 。該ID用於外部查詢的 WHERE 子句中,以便檢索出這個供應商生
產的所有物品
現在來看使用聯結的相同查詢:
此查詢中需要的兩個表實際上是相同的表,因此 products 表在
FROM 子句中出現了兩次。雖然這是完全合法的,但對 products
的引用具有二義性,因為MySQL不知道你引用的是 products 表中的哪個
實例。
為解決此問題,使用了表別名。 products 的第一次出現為別名 p1 ,
第二次出現為別名 p2 。現在可以將這些別名用作表名。例如, SELECT 語
句使用 p1 首碼明確地給出所需列的全名。如果不這樣,MySQL將返回錯
誤,因為分別存在兩個名為 prod_id 、 prod_name 的列。MySQL不知道想
要的是哪一個列(即使它們事實上是同一個列)。 WHERE (通過匹配 p1 中
的 vend_id 和 p2 中的 vend_id )首先聯結兩個表,然後按第二個表中的
prod_id 過濾數據,返回所需的數據。
用自聯結而不用子查詢 自聯結通常作為外部語句用來替代
從相同表中檢索數據時使用的子查詢語句。雖然最終的結果是
相同的,但有時候處理聯結遠比處理子查詢快得多。應該試一
下兩種方法,以確定哪一種的性能更好
自然聯結
無論何時對錶進行聯結,應該至少有一個列出現在不止一個表中(被
聯結的列)。標準的聯結(前一章中介紹的內部聯結)返回所有數據,甚
至相同的列多次出現。自然聯結排除多次出現,使每個列只返回一次。
自然聯結是這樣一種聯結,其中你只能選擇那些唯一的列。這一
般是通過對錶使用通配符( SELECT * ),對所有其他表的列使用明確的子
集來完成的。下麵舉一個例子:
在這個例子中,通配符只對第一個表使用。所有其他列明確列
出,所以沒有重覆的列被檢索出來
事實上,迄今為止我們建立的每個內部聯結都是自然聯結,很可能
我們永遠都不會用到不是自然聯結的內部聯結
外部聯結
許多聯結將一個表中的行與另一個表中的行相關聯。但有時候會需
要包含沒有關聯行的那些行
下麵的 SELECT 語句給出一個簡單的內部聯結。它檢索所有客戶及其
訂單
SELECT 語句使用了關
鍵字 OUTER JOIN 來指定聯結的類型(而不是在 WHERE 子句中指
定)。但是,與內部聯結關聯兩個表中的行不同的是,外部聯結還包括沒
有關聯行的行。在使用 OUTER JOIN 語法時,必須使用 RIGHT 或 LEFT 關鍵字
指定包括其所有行的表( RIGHT 指出的是 OUTER JOIN 右邊的表,而 LEFT
指出的是 OUTER JOIN 左邊的表)。上面的例子使用 LEFT OUTER JOIN 從 FROM
子句的左邊表( customers 表)中選擇所有行。為了從右邊的表中選擇所
沒有 = 操作符 MySQL不支持簡化字元 = 和 =* 的使用,這兩
種操作符在其他DBMS中是很流行的。
外部聯結的類型 存在兩種基本的外部聯結形式:左外部聯結
和右外部聯結。它們之間的唯一差別是所關聯的表的順序不
同。換句話說,左外部聯結可通過顛倒 FROM 或 WHERE 子句中
有行,應該使用 RIGHT OUTER JOIN
使用帶聚集函數的聯結
聚集函數用來彙總數據。雖然至今為止聚集函數
的所有例子只是從單個表彙總數據,但這些函數也可以與聯結一起使用
此 SELECT 語句使用 INNER JOIN 將 customers 和 orders 表互相關聯。
GROUP BY 子句按客戶分組數據,因此,函數調用 COUNT
(orders.order_num) 對每個客戶的訂單計數,將它作為 num_ord 返回
這個例子使用左外部聯結來包含所有客戶,甚至包含那些沒有
任何下訂單的客戶。結果顯示也包含了客戶 Mouse House ,它
有 0 個訂單。
使用聯結和聯結條件
在總結關於聯結的這兩章前,有必要彙總一下關於聯結及其使用的
某些要點。
- 註意所使用的聯結類型。一般我們使用內部聯結,但使用外部聯
結也是有效的。 - 保證使用正確的聯結條件,否則將返回不正確的數據。
- 應該總是提供聯結條件,否則會得出笛卡兒積。
- 在一個聯結中可以包含多個表,甚至對於每個聯結可以採用不同
的聯結類型。雖然這樣做是合法的,一般也很有用,但應該在一
起測試它們前,分別測試每個聯結。這將使故障排除更為簡單。
本章從講授如何以及為什麼要使用
別名開始,然後討論不同的聯結類型及對每種類型的聯結使用的各種語
法形式。我們還介紹瞭如何與聯結一起使用聚集函數,以及在使用聯結
時應該註意的某些問題