MySQL多表關聯查詢

Simple_Yang92發表於2018-01-27

SQL 連線(JOIN) 子句用於把來自兩個或多個表的行結合起來,基於這些表之間的共同欄位。連線的結果可以在邏輯上看作是由SELECT語句指定的列組成的新表。左連線與右連線的左右指的是以兩張表中的哪一張為基準,它們都是外連線。外連線就好像是為非基準表新增了一行全為空值的萬能行,用來與基準表中找不到匹配的行進行匹配。假設兩個沒有空值的表進行左連線,左表是基準表,左表的所有行都出現在結果中,右表則可能因為無法與基準表匹配而出現是空值的欄位。


不同的 SQL JOIN

在我們繼續講解例項之前,我們先列出您可以使用的不同的 SQL JOIN 型別:

 INNER JOIN:如果表中有至少一個匹配,則返回行

  • LEFT JOIN:即使右表中沒有匹配,也從左表返回所有的行
  • RIGHT JOIN:即使左表中沒有匹配,也從右表返回所有的行
  • FULL JOIN:只要其中一個表中存在匹配,則返回行(MySQL不支援FULL JOIN)
例項表1:
mysql> select * from websites;
+----+---------------+---------------------------+-------+---------+
| id | name          | url                       | alexa | country |
+----+---------------+---------------------------+-------+---------+
|  1 | Google        | https://www.google.cm/    |     1 | USA     |
|  2 | 淘寶          | https://www.taobao.com/   |    13 | CN      |
|  3 | 菜鳥教程      | http://www.runoob.com/    |  4689 | CN      |
|  4 | 微博          | http://weibo.com/         |    20 | CN      |
|  5 | Facebook      | https://www.facebook.com/ |     3 | USA     |
|  6 | stackoverflow | http://stackoverflow.com/ |     0 | IND     |
|  7 | 百度          | https://www.baidu.com/    |     4 | CN      |
+----+---------------+---------------------------+-------+---------+
7 rows in set
例項表2:
mysql> select * from access_log;
+-----+---------+-------+------------+
| aid | site_id | count | date       |
+-----+---------+-------+------------+
|   1 |       1 |    45 | 2016-05-10 |
|   2 |       3 |   100 | 2016-05-13 |
|   3 |       1 |   230 | 2016-05-14 |
|   4 |       2 |    10 | 2016-05-14 |
|   5 |       5 |   205 | 2016-05-14 |
|   6 |       4 |    13 | 2016-05-15 |
|   7 |       3 |   220 | 2016-05-15 |
|   8 |       5 |   545 | 2016-05-16 |
|   9 |       3 |   201 | 2016-05-17 |
+-----+---------+-------+------------+
9 rows in set

取交集:

mysql> SELECT w.name, a.count, a.date FROM websites w, access_log a WHERE w.id = a.site_id;
+----------+-------+------------+
| name     | count | date       |
+----------+-------+------------+
| Google   |    45 | 2016-05-10 |
| 菜鳥教程 |   100 | 2016-05-13 |
| Google   |   230 | 2016-05-14 |
| 淘寶     |    10 | 2016-05-14 |
| Facebook |   205 | 2016-05-14 |
| 微博     |    13 | 2016-05-15 |
| 菜鳥教程 |   220 | 2016-05-15 |
| Facebook |   545 | 2016-05-16 |
| 菜鳥教程 |   201 | 2016-05-17 |
+----------+-------+------------+
9 rows in set
mysql> SELECT w.name, a.count, a.date FROM websites w INNER JOIN access_log a ON w.id = a.site_id;
+----------+-------+------------+
| name     | count | date       |
+----------+-------+------------+
| Google   |    45 | 2016-05-10 |
| 菜鳥教程 |   100 | 2016-05-13 |
| Google   |   230 | 2016-05-14 |
| 淘寶     |    10 | 2016-05-14 |
| Facebook |   205 | 2016-05-14 |
| 微博     |    13 | 2016-05-15 |
| 菜鳥教程 |   220 | 2016-05-15 |
| Facebook |   545 | 2016-05-16 |
| 菜鳥教程 |   201 | 2016-05-17 |
+----------+-------+------------+
9 rows in set

註釋: INNER JOIN 與 JOIN 是相同的。

取左並集:

註釋:在某些資料庫中,LEFT JOIN 稱為 LEFT OUTER JOIN。
LEFT JOIN 關鍵字從左表(table1)返回所有的行,即使右表(table2)中沒有匹配。如果右表中沒有匹配,則結果為 NULL
mysql> SELECT w.name, a.count, a.date FROM websites w LEFT JOIN access_log a ON w.id = a.site_id;
+---------------+-------+------------+
| name          | count | date       |
+---------------+-------+------------+
| Google        |    45 | 2016-05-10 |
| 菜鳥教程      |   100 | 2016-05-13 |
| Google        |   230 | 2016-05-14 |
| 淘寶          |    10 | 2016-05-14 |
| Facebook      |   205 | 2016-05-14 |
| 微博          |    13 | 2016-05-15 |
| 菜鳥教程      |   220 | 2016-05-15 |
| Facebook      |   545 | 2016-05-16 |
| 菜鳥教程      |   201 | 2016-05-17 |
| stackoverflow | NULL  | NULL       |
| 百度          | NULL  | NULL       |
+---------------+-------+------------+
11 rows in set



取右並集:


註釋:在某些資料庫中,RIGHT JOIN 稱為 RIGHT OUTER JOIN。
RIGHT JOIN 關鍵字從右表(table2)返回所有的行,即使左表(table1)中沒有匹配。如果左表中沒有匹配,則結果為 NULL。

mysql> SELECT Websites.name, access_log.count, access_log.date
FROM access_log
RIGHT JOIN Websites
ON access_log.site_id=Websites.id;
+---------------+-------+------------+
| name          | count | date       |
+---------------+-------+------------+
| Google        |    45 | 2016-05-10 |
| 菜鳥教程      |   100 | 2016-05-13 |
| Google        |   230 | 2016-05-14 |
| 淘寶          |    10 | 2016-05-14 |
| Facebook      |   205 | 2016-05-14 |
| 微博          |    13 | 2016-05-15 |
| 菜鳥教程      |   220 | 2016-05-15 |
| Facebook      |   545 | 2016-05-16 |
| 菜鳥教程      |   201 | 2016-05-17 |
| stackoverflow | NULL  | NULL       |
| 百度          | NULL  | NULL       |
+---------------+-------+------------+
11 rows in set

取全集:

MySQL Full Join的實現因為MySQL不支援FULL JOIN,下面是替代方法

left join + union(可去除重複資料)+ right join

select * from A left join B on A.id = B.id (where 條件)union

select * from A right join B on A.id = B.id (where條件);

mysql> SELECT * FROM websites LEFT JOIN access_log ON Websites.id=access_log.site_id 
UNION SELECT * FROM websites RIGHT JOIN access_log ON Websites.id=access_log.site_id;
+----+---------------+---------------------------+-------+---------+------+---------+-------+------------+
| id | name          | url                       | alexa | country | aid  | site_id | count | date       |
+----+---------------+---------------------------+-------+---------+------+---------+-------+------------+
|  1 | Google        | https://www.google.cm/    |     1 | USA     |    1 |       1 |    45 | 2016-05-10 |
|  3 | 菜鳥教程      | http://www.runoob.com/    |  4689 | CN      |    2 |       3 |   100 | 2016-05-13 |
|  1 | Google        | https://www.google.cm/    |     1 | USA     |    3 |       1 |   230 | 2016-05-14 |
|  2 | 淘寶          | https://www.taobao.com/   |    13 | CN      |    4 |       2 |    10 | 2016-05-14 |
|  5 | Facebook      | https://www.facebook.com/ |     3 | USA     |    5 |       5 |   205 | 2016-05-14 |
|  4 | 微博          | http://weibo.com/         |    20 | CN      |    6 |       4 |    13 | 2016-05-15 |
|  3 | 菜鳥教程      | http://www.runoob.com/    |  4689 | CN      |    7 |       3 |   220 | 2016-05-15 |
|  5 | Facebook      | https://www.facebook.com/ |     3 | USA     |    8 |       5 |   545 | 2016-05-16 |
|  3 | 菜鳥教程      | http://www.runoob.com/    |  4689 | CN      |    9 |       3 |   201 | 2016-05-17 |
|  6 | stackoverflow | http://stackoverflow.com/ |     0 | IND     | NULL | NULL    | NULL  | NULL       |
|  7 | 百度          | https://www.baidu.com/    |     4 | CN      | NULL | NULL    | NULL  | NULL       |
+----+---------------+---------------------------+-------+---------+------+---------+-------+------------+
11 rows in set

SQL UNION 操作符合並兩個或多個 SELECT 語句的結果。


SQL UNION 操作符

UNION 操作符用於合併兩個或多個 SELECT 語句的結果集。

請注意,UNION 內部的每個 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的資料型別。同時,每個 SELECT 語句中的列的順序必須相同。

SQL UNION 語法

相關文章