1. 程式人生 > >SQL學習之--聯結表

SQL學習之--聯結表

SQL最強大的功能之一就是能在資料查詢的執行中聯結(join)表。

關係表
理解關係表,可以來看一個例子。
有一個包含產品目錄的資料庫表,其中每類物品佔一行。對於每一種物品,要儲存的資訊包括產品描述,,價格,以及生產該產品的供應商。
把它們放在一張表中必然會有重複的資訊,一個供應商的資訊將重複在他生產的產品後出現,相同的資料出現多次絕不是一件好事,這是關係資料庫設計的基礎。關係表的設計就是要把資訊分解成多個表,一類資料一個表。各表通過某些共同的值互相關聯。
在這個例子中可建立兩個表:一個儲存供應商資訊(products),一個儲存商品資訊(vendors)。vendors表的主鍵與products表關聯。

建立聯結

SELECT vend_name, prod_name, prod_price
FROM vendors, products
WHERE vendors.vend_id = products.vend_id;

內聯結(inner join)

內聯結也稱為等值聯結。

SELECT vend_name, prod_name, prod_price
FROM vendors INNER JOIN products
 ON vendors.vend_id = products.vend_id;

注意此程式碼與上面程式碼的不同之處。

聯結多個表

FROM…WHERE版本。

SELECT vend_name, prod_name, prod_price, quantity
FROM vendors, products, orderitems
WHERE vendors.vend_id = products.vend_id
  AND orderitems.prod_id = products.prod_id
  AND order_num = 20007;

上面程式碼塊中,WHERE子句中,前兩個條件定義了三個表的聯結關係,後一個用來過濾所要的資訊。

FROM…ON版本。

SELECT vend_name, prod_name, prod_price, quantity
FROM
vendors INNER JOIN (products, orderitems) ON vendors.vend_id = products.vend_id AND orderitems.prod_id = products.prod_id AND order_num = 20007;

聯結表的最大數要參照具體的DBMS,MySQL的限制是?沒找到

別名

在SQL中可以給列名,表名和計算欄位使用別名。

SELECT vend_name, prod_name, prod_price, quantity
FROM vendors AS V, products AS P, orderitems AS OI
WHERE V.vend_id = P.vend_id
  AND OI.prod_id = P.prod_id
  AND order_num = 20007;

高階聯結

自聯結(self-join)

SELECT cust_id, cust_name, cust_contant
FROM customers
WHERE cust_name = (SELECT cust_name
                   FROM customers
                   WHERE cust_contact = 'Jim');

等價於

SELECT C1.cust_id, C1.cust_name, C1.cust_contant   #因為cust_XX都有了兩列,所以必須用完全限制名
FROM customers AS C1, customers AS C2
WHERE C1.cust_name = C2.cust_name                #首先要聯結兩個表
 AND C2.cust_contact = 'Jim';                   #過濾資料

一般能用自聯結的時候不用子查詢。

自然聯結(natural join)

自然聯結排除多次出現,使每一列只返回一次。通常使用對一個表使用萬用字元,其他表的列使用明確的子集。

SELECT C.*, V.vend_name, P.prod_name, P.prod_price, OI.quantity

外聯結(outer join)

許多聯結將一個表中的行與另一個表中的行相關聯,但有時候需要包含沒有關聯的那些行。例:對每個顧客下的訂單計數,包括至今未下訂單的顧客。

SELECT c.cust_id, o.order_num
FROM customers AS c LEFT OUTER JOIN orders AS o
 ON c.cust_id = o.cust_id;         #聯結條件

外聯結:聯結包含了那些在相關表中沒有關聯行的行。即,在包含了orders表中沒有關聯行的,customers表中的行。

  • LEFT:選擇左邊(OUTER JOIN的左邊)的表的所有行;
  • RIGHT:選擇右邊表的所有行;
  • FULL:兩個表;

使用帶聚集函式的聯結

檢索所有顧客以及每個顧客下的訂單數。

SELECT c.cust_id, COUNT(o.order_num) AS num_ord
FROM customers AS c INNER JOIN orders AS o
 ON c.cust_id = o.cust_id
GROUP BY c.cust_id;      

使用聯結的要點

  • 使用正確的聯結條件,並且總是提供聯結條件,否則會得出笛卡爾積;
  • 在一個聯結中可以包含多個表,升值對每個聯結采取不同的聯結型別。但在一起測試它們前請分別測試每個聯結。
參考

《SQL必知必會》