MySQL必知必會(四)閱讀筆記
阿新 • • 發佈:2020-02-25
第十四章 使用子查詢
子查詢
例:查詢訂購物品TNT2的所有顧客資訊
//1:檢索包含物品TNT2的所有訂單的編號 SELECT order_num FROM orderitems WHERE prod_id = 'TNT2'; //2檢索具有前一步驟列出的訂單編號的所有客戶的id SELECT cust_id FROM orders WHERE order_num IN (20005,20007); //3檢索上一步所有客戶id的全部資訊 SELECT cust_name,cust_contact FROM customers WHERE cust_id IN (10001,10004); //將上面3步合併 SELECT cust_name,cust_contact FROM customers WHERE cust_id IN (SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id = 'TNT2'));
作為計算欄位使用子查詢
顯示customers表中每一個客戶的訂單總數
SELECT cust_id,cust_name,cust_state,(SELECT count(*)
FROM orders
WHERE orders.cust_id = customers.cust_id) AS num_order
FROM customers
ORDER BY num_order
聯結表
建立聯結
外來鍵為某個表中的一列,它包含另一個表的主鍵值,定義了兩個表之間的關係
優點
- 供應商資訊不重複,從而不浪費時間和空間;
- 如果供應商資訊變動,可以只更新vendors表中的單個記錄,相關表中的資料不用改動;
- 由於資料無重複,顯然資料是一致的,這使得處理資料更簡單。
SELECT vend_name,prod_name,prod_price
FROM vendors v,products p
WHERE v.vend_id = p.vend_id
ORDER BY vend_name,prod_name
笛卡兒積(cartesian product) 由沒有聯結條件的表關係返回的結果為笛卡兒積。檢索出的行的數目將是第一個表中的行數乘以第二個表中的行數。
SELECT vend_name,products p
//將顯示笛卡兒積
等值聯結
目前為止所用的聯結稱為等值聯結(equijoin),它基於兩個表之間的相等測試。這種聯結也稱為內部聯結。其實,對於這種聯結可以使用稍微不同的語法來明確指定聯結的型別。下面的SELECT語句返回與前面例子完全相同的資料:
SELECT vend_name,prod_price
FROM vendors v
INNER JOIN products p ON v.vend_id = p.vend_id
ORDER BY vend_name,prod_name
聯結多個表
SELECT prod_name,vend_name,prod_price,quantity
FROM products p,orderitems o,vendors v
WHERE p.vend_id =v.vend_id
AND o.prod_id = p.prod_id
AND o.order_num = 20005;
第十六章 建立高階聯結
別名除了用於列名和計算欄位外, SQL還允許給表名起別名。這樣做有兩個主要理由:
- 縮短SQL語句;
- 允許在單條SELECT語句中多次使用相同的表。
使用不同型別的聯結
四種聯結:等值聯結、自聯結、自然聯結和外部聯結。
自聯結
假如你發現某物品(其ID為DTNTR)存在問題,因此想知道生產該物品的供應商生產的其他物品是否也存在這些問題。此查詢要求首先找到生產ID為DTNTR的物品的供應商,然後找出這個供應商生產的其他物品。
SELECT p1.prod_id,p1.prod_name
FROM products p1,products p2
WHERE p1.vend_id = p2.vend_id
AND p2.prod_id = 'DTNTR';
用自聯結而不用子查詢 自聯結通常作為外部語句用來替代從相同表中檢索資料時使用的子查詢語句。雖然最終的結果是相同的,但有時候處理聯結遠比處理子查詢快得多。應該試一下兩種方法,以確定哪一種的效能更好。
自然聯結
無論何時對錶進行聯結,應該至少有一個列出現在不止一個表中(被聯結的列)。標準的聯結返回所有資料,甚至相同的列多次出現。 自然聯結排除多次出現,使每個列只返回一次。
外部聯結
SELECT c.cust_id,o.order_num
FROM customers c
LEFT JOIN orders o ON c.cust_id = o.cust_id