MySQL 教材:單邊接合

上節中,使用

select name, zip, zone, area, addressno
from list join address join ZIP
where list.addressid = address.id and address.zipid = ZIP.id
and status = 'S' and gender = 'M';
而沒有找到相符的結果, 意義是「它通常代表的是中大數學沒有男職員」。
為何是「通常」? 條件是由 and 構成,只要有任何一個不成立,就不會被列出來。 但資料都應該是正確的,怎麼可能會讓 addressid 或 zipid 找不到對映的資料呢? 答案就是沒有 (NULL) 在做祟。

NULL 出現在資料表內是是很常見的,常會有資料遺失或缺少, 或是代表某些特殊意義。 但在某些情況下,還是希望能將這些資料列出來, 好讓我們知道並不是沒有這種人,而是沒有資料。
看個例子:

customers 表存放客戶的基本資料:

+----+--------+-----------------+
| id | name   | city            |
+----+--------+-----------------+
|  1 | Smith  | Boston          |
|  2 | Wang   | Washington D.C. |
|  3 | Arthur | Seatlle         |
|  4 | Jones  | Los Angel       |
|  5 | Tomas  | San Fracisco    |
+----+--------+-----------------+
orders 內存著顧客訂購書籍的資訊:
+----+------------+------------+----------+
| id | customerid | isdn       | quantity |
+----+------------+------------+----------+
|  1 |          1 | 0588936749 | 2        |
|  2 |          2 | 9578654472 | 1        |
|  3 |          3 | 9578658023 | 1        |
|  4 |          3 | 0912648719 | 3        |
|  5 |          4 | 0219385764 | 1        |
+----+------------+------------+----------+
想知道查詢所有顧客,並順便知道他們訂了那些東西, 若使用一般的接合,只會列出有訂東西的客戶:
select customers.id, customers.name, orders.id
from customers join orders
where customers.id = orders.customerid;
+----+--------+----+
| id | name   | id |
+----+--------+----+
|  1 | Smith  |  1 |
|  2 | Wang   |  2 |
|  3 | Arthur |  3 |
|  3 | Arthur |  4 |
|  4 | Jones  |  5 |
+----+--------+----+
但用了單邊接合,就可以出現我們想要的資料:
select customers.id, customers.name, orders.id
from customers left join orders
on customers.id = orders.customerid;
+----+--------+------+
| id | name   | id   |
+----+--------+------+
|  1 | Smith  |    1 |
|  2 | Wang   |    2 |
|  3 | Arthur |    3 |
|  3 | Arthur |    4 |
|  4 | Jones  |    5 |
|  5 | Tomas  | NULL |
+----+--------+------+
如此可以很簡單的知道客戶中只有 Tomas 還沒有訂購資料, 或許是剛註冊完還沒送出訂購單,也可能是註冊好玩的。

請注意 left join 對應的條件子句是 "on", 若使用 "where" 系統會解讀為給原始資料表的條件, 習題中將有例子給同學練習。 MySQL 僅提供一種單邊接合 -- 左側接合 (left join), 直觀的想法是,以將 "left join" 左側的資料表為主, 去尋找 "left join" 右側資料表有沒有符合 "on" 後所附的條件, 有就將它列出來,若不只一個會全列,找不到的話會塞個 "NULL" 並印出來。

習題
  1. 某計概共有三位同學修課
    select * from students;
    +----+---------+
    | id | name    |
    +----+---------+
    |  1 | 王大明  |
    |  2 | 林小祺  |
    |  3 | 訐譙龍  |
    +----+---------+
    
    小考成績( studentid--對應到 students 表的 id, number--小考編號, grade--分數 )
    select * from quiz;
    +----+-----------+--------+-------+
    | id | studentid | number | grade |
    +----+-----------+--------+-------+
    |  1 |         1 |      1 |    72 |
    |  2 |         3 |      2 |    93 |
    |  3 |         3 |      1 |    77 |
    |  4 |         2 |      3 |    98 |
    |  5 |         1 |      3 |    84 |
    |  6 |         2 |      2 |    66 |
    |  7 |         3 |      3 |    81 |
    +----+-----------+--------+-------+
    
    請列出二次小考的成積, 缺考以 "NULL" 表示。
[BCC16-A]
林勁伍 (02/10/06) ---
[Prev] [Next] [Up]