1. 程式人生 > 實用技巧 >MySQL基礎之MySQL必知必會(十六)建立高階聯結

MySQL基礎之MySQL必知必會(十六)建立高階聯結

使用表別名

SQL允許給表取別名, 這樣做的理由是

  • 縮短SQL語句
  • 允許在單條SELECT語句中多次使用相同的表
MariaDB [crashcourse]> 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 = 'TNT2';
+----------------+--------------+
| cust_name      | cust_contact |
+----------------+--------------+ | Coyote Inc. | Y Lee | | Yosemite Place | Y Sam | +----------------+--------------+ 2 rows in set (0.002 sec) MariaDB [crashcourse]>

表別名只在查詢中使用, 與列別名不一樣, 表別名不返回到客戶機。

使用不同型別的聯結

自聯結

使用表別名的主要原因之一是能在單條SELECT語句中不止一次引用相同的表。

MariaDB [crashcourse]>
SELECT p1.prod_id, p1.prod_name FROM products AS p1, products AS p2 WHERE p1.vend_id=p2.vend_id AND p2.prod_id = 'DTNTR'; +---------+----------------+ | prod_id | prod_name | +---------+----------------+ | DTNTR | Detonator | | FB | Bird seed | | FC | Carrots | | SAFE |
Safe | | SLING | Sling | | TNT1 | TNT (1 stick) | | TNT2 | TNT (5 sticks) | +---------+----------------+ 7 rows in set (0.001 sec) MariaDB [crashcourse]>

自聯結通常作為外部語句用來替代從相同表中檢索資料時使用的子查詢語句。雖然最終結果相同, 但有時候處理聯結遠比處理子查詢快得多。

自然聯結

無論何時對錶進行聯結, 應該至少有一個列出現在不止一個表中。標準的聯結返回所有資料, 甚至相同的列多次出現。自然聯結排除多次出現, 使每個列只返回一次。

系統完不成這項操作, 需要自己完成。自然聯結是這樣的一種聯結, 其中你只能選擇那些唯一的列。這一般是通過對錶使用萬用字元(SELECT *), 對所有其他表的列使用明確的子集來完成。

MariaDB [crashcourse]> 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="FB";
+---------+-------------+----------------+-----------+------------+----------+--------------+--------------+-----------------+-----------+---------------------+---------+----------+------------+
| cust_id | cust_name   | cust_address   | cust_city | cust_state | cust_zip | cust_country | cust_contact | cust_email      | order_num | order_date          | prod_id | quantity | item_price |
+---------+-------------+----------------+-----------+------------+----------+--------------+--------------+-----------------+-----------+---------------------+---------+----------+------------+
|   10001 | Coyote Inc. | 200 Maple Lane | Detroit   | MI         | 44444    | USA          | Y Lee        | ylee@coyote.com |     20005 | 2005-09-01 00:00:00 | FB      |        1 |      10.00 |
|   10001 | Coyote Inc. | 200 Maple Lane | Detroit   | MI         | 44444    | USA          | Y Lee        | ylee@coyote.com |     20009 | 2005-10-08 00:00:00 | FB      |        1 |      10.00 |
+---------+-------------+----------------+-----------+------------+----------+--------------+--------------+-----------------+-----------+---------------------+---------+----------+------------+
2 rows in set (0.001 sec)

MariaDB [crashcourse]> 

外部聯結

聯結包含了那些在相關表中沒有的關聯行的行。這種型別的聯結稱為外部聯結。

MariaDB [crashcourse]> SELECT customers.cust_id, orders.order_num FROM customers LEFT OUTER JOIN orders ON customers.cust_id=orders.cust_id;
+---------+-----------+
| cust_id | order_num |
+---------+-----------+
|   10001 |     20005 |
|   10001 |     20009 |
|   10002 |      NULL |
|   10003 |     20006 |
|   10004 |     20007 |
|   10005 |     20008 |
+---------+-----------+
6 rows in set (0.001 sec)

MariaDB [crashcourse]> 

這條SELECT語句使用了關鍵字OUTER JOIN來指定聯結的型別。與內部聯結關聯兩個表中的行不同的是, 外部聯結還包括沒有關聯行的行。

在使用OUTER JOIN語法時, 必須使用RIGHT或LEFT關鍵字指定包括其所有行的表(RIGHT指出的是OUTER JOIN右邊的表, 而LEFT指出的是OUTER JOIN左邊的表)。

使用帶聚集函式的聯結

MariaDB [crashcourse]> SELECT customers.cust_name, 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;
+----------------+---------+---------+
| cust_name      | cust_id | num_ord |
+----------------+---------+---------+
| Coyote Inc.    |   10001 |       2 |
| Wascals        |   10003 |       1 |
| Yosemite Place |   10004 |       1 |
| E Fudd         |   10005 |       1 |
+----------------+---------+---------+
4 rows in set (0.002 sec)

MariaDB [crashcourse]> 

使用聯結和聯結關係

  • 注意所使用的聯結型別。一般使用內部聯結, 但使用外部聯結也是有效的。
  • 保證使用正確的聯結條件。否則將返回不正確的資料
  • 應該總是提供聯結條件, 否則會得出笛卡爾積
  • 在一個聯結表中可以包含多個表, 甚至對於每個聯結可以採用不同的聯結型別。