MySQL Crash Course #08# Chapter 16. Using Different Join Types
記文檔還是相當重要的!
索引
- 假名的三個用途
- 自交(Self Joins)
- 自然交(Natural Joins)
- Outer Joins
Using Table Aliases
- Using aliases for column names and calculated fields
-
To shorten the SQL syntax
-
To enable multiple uses of the same table within a single SELECT statement
自交
像下面這樣的叫做“自交” ↓
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‘;
Self Joins Instead of Subqueries Self joins are often used to replace statements using subqueries that retrieve data from the same table as the outer statement. Although the end result is the same, sometimes these joins execute far more quickly than they do subqueries. It is us
接下來用於實驗的兩張表:
-- master
+-----------+-------------+ | master_id | master_name | +-----------+-------------+ | 1001 | 王二牠 | | 1002 | 李明顠 | | 1003 | 田中吠 | | 1004 | 陸大襠 | +-----------+-------------+
-- pet
+--------+----------+----------+-----------+ | pet_id | pet_type | pet_name | master_id | +--------+----------+----------+-----------+ | 8881 | NULL | 飿¡¶ | 1001 | | 8882 | dog | 小白 | 1002 | | 8883 | cat | 老黃 | 1003 | +--------+----------+----------+-----------+
無約束自交,原來 3 條 結果 3 × 3 ↓
mysql> SELECT * -> FROM pet AS p1, pet AS p2; +--------+----------+----------+-----------+--------+----------+----------+-----------+ | pet_id | pet_type | pet_name | master_id | pet_id | pet_type | pet_name | master_id | +--------+----------+----------+-----------+--------+----------+----------+-----------+ | 8881 | NULL | 飿¡¶ | 1001 | 8881 | NULL | 飿¡¶ | 1001 | | 8882 | dog | 小白 | 1002 | 8881 | NULL | 飿¡¶ | 1001 | | 8883 | cat | 老黃 | 1003 | 8881 | NULL | 飿¡¶ | 1001 | | 8881 | NULL | 飿¡¶ | 1001 | 8882 | dog | 小白 | 1002 | | 8882 | dog | 小白 | 1002 | 8882 | dog | 小白 | 1002 | | 8883 | cat | 老黃 | 1003 | 8882 | dog | 小白 | 1002 | | 8881 | NULL | 飿¡¶ | 1001 | 8883 | cat | 老黃 | 1003 | | 8882 | dog | 小白 | 1002 | 8883 | cat | 老黃 | 1003 | | 8883 | cat | 老黃 | 1003 | 8883 | cat | 老黃 | 1003 | +--------+----------+----------+-----------+--------+----------+----------+-----------+
自然交。。
就是可以自動消除相同字段的一種交,但是 MySQL 並沒有實現這種交,如果你 像下面這樣查 就會看到好多相同字段:
SELECT * 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 | cust_id | order_num | order_item | prod_id | quantity | item_price |
所以,要實現自然交就 只能自己具體指明字段了:
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‘;
MySQL 不實現自然交:
mysql> SELECT * -> FROM master AS m, pet AS p -> WHERE m.master_id = p.master_id; +-----------+-------------+--------+----------+----------+-----------+ | master_id | master_name | pet_id | pet_type | pet_name | master_id | +-----------+-------------+--------+----------+----------+-----------+ | 1001 | 王二牠 | 8881 | NULL | 飿¡¶ | 1001 | | 1002 | 李明顠 | 8882 | dog | 小白 | 1002 | | 1003 | 田中吠 | 8883 | cat | 老黃 | 1003 | +-----------+-------------+--------+----------+----------+-----------+ 3 rows in set (0.00 sec)
實現自然交:
mysql> SELECT master_name, p.* -> FROM master AS m, pet AS p -> WHERE m.master_id = p.master_id; +-------------+--------+----------+----------+-----------+ | master_name | pet_id | pet_type | pet_name | master_id | +-------------+--------+----------+----------+-----------+ | 王二牠 | 8881 | NULL | 飿¡¶ | 1001 | | 李明顠 | 8882 | dog | 小白 | 1002 | | 田中吠 | 8883 | cat | 老黃 | 1003 | +-------------+--------+----------+----------+-----------+
PS. FROM 裏面 AS 的假名在 SELECT 中是可以用的。
Outer Joins
The join includes table rows that have no associated rows in the related table. This type of join is called an outer join. But unlike inner joins, which relate rows in both tables, outer joins also include rows with no related rows.
在講到 OUTER JOIN 的同時就不得不提到 INNER JOIN ,推薦閱讀這篇文章 Inner Join vs. Outer Join
真 · INNER JOIN ↓
mysql> SELECT master_name, p.* -> FROM master AS m INNER JOIN pet AS p -> ON m.master_id = p.master_id; +-------------+--------+----------+----------+-----------+ | master_name | pet_id | pet_type | pet_name | master_id | +-------------+--------+----------+----------+-----------+ | 王二牠 | 8881 | NULL | 飿¡¶ | 1001 | | 李明顠 | 8882 | dog | 小白 | 1002 | | 田中吠 | 8883 | cat | 老黃 | 1003 | +-------------+--------+----------+----------+-----------+
因為我個人認為沒有人會需要 X * X 的 那種表 所以 自己 把 那種 不加 ON 後面的相等約束 的 表 叫 偽 · INNER JOIN
LEFT OUTER JOIN ↓
mysql> SELECT master_name, p.* -> FROM master AS m LEFT OUTER JOIN pet AS p -> ON m.master_id = p.master_id; +-------------+--------+----------+----------+-----------+ | master_name | pet_id | pet_type | pet_name | master_id | +-------------+--------+----------+----------+-----------+ | 王二牠 | 8881 | NULL | 飿¡¶ | 1001 | | 李明顠 | 8882 | dog | 小白 | 1002 | | 田中吠 | 8883 | cat | 老黃 | 1003 | | 陸大襠 | NULL | NULL | NULL | NULL | +-------------+--------+----------+----------+-----------+
RIGHT OUTER JOIN ↓
mysql> SELECT master_name, p.* -> FROM master AS m RIGHT OUTER JOIN pet AS p -> ON m.master_id = p.master_id; +-------------+--------+----------+----------+-----------+ | master_name | pet_id | pet_type | pet_name | master_id | +-------------+--------+----------+----------+-----------+ | 王二牠 | 8881 | NULL | 飿¡¶ | 1001 | | 李明顠 | 8882 | dog | 小白 | 1002 | | 田中吠 | 8883 | cat | 老黃 | 1003 | +-------------+--------+----------+----------+-----------+
PS. the two types of outer join can be used interchangeably, and the decision about which one is used is based purely on convenience.
MySQL Crash Course #08# Chapter 16. Using Different Join Types