1. 程式人生 > >MySQL Crash Course #08# Chapter 16. Using Different Join Types

MySQL Crash Course #08# Chapter 16. Using Different Join Types

字段 execute chapter _id BE all sam https pri

記文檔還是相當重要的!

索引

  1. 假名的三個用途
  2. 自交(Self Joins)
  3. 自然交(Natural Joins)
  4. 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

ually worth experimenting with both to determine which performs better.

接下來用於實驗的兩張表:

-- 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