成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

圖解MySQL里的各種 JOIN,看完不懂來找我!

數據庫 MySQL
從業以來主要在做客戶端,用到的數據庫都是表結構比較簡單的 SQLite,以我那還給老師一大半的 SQL 水平倒也能對付。

 從業以來主要在做客戶端,用到的數據庫都是表結構比較簡單的 SQLite,以我那還給老師一大半的 SQL 水平倒也能對付。現在偶爾需要到后臺的 SQL Server 里追查一些數據問題,就顯得有點捉襟見肘了,特別是各種 JOIN,有時候傻傻分不清楚,于是索性弄明白并做個記錄。

 

[[274993]]

前言

在各種問答社區里談及 SQL 里的各種 JOIN 之間的區別時,最被廣為引用的是 CodeProject 上 C.L. Moffatt 的文章 Visual Representation of SQL Joins,他確實講得簡單明了,使用文氏圖來幫助理解,效果明顯。本文將沿用他的講解方式,稍有演繹,可以視為該文較為粗糙的中譯版。

約定

下文將使用兩個數據庫表 Table_A 和 Table_B 來進行示例講解,其結構與數據分別如下:

  1. mysql> SELECT * FROM Table_A ORDER BY PK ASC
  2. +----+---------+ 
  3. | PK | Value   | 
  4. +----+---------+ 
  5. |  1 | both ab | 
  6. |  2 | only a  | 
  7. +----+---------+ 
  8. rows in set (0.00 sec) 
  9.  
  10. mysql> SELECT * from Table_B ORDER BY PK ASC
  11. +----+---------+ 
  12. | PK | Value   | 
  13. +----+---------+ 
  14. |  1 | both ab | 
  15. |  3 | only b  | 
  16. +----+---------+ 
  17. rows in set (0.00 sec) 

其中 PK 為 1 的記錄在 Table_A 和 Table_B 中都有,2 為 Table_A 特有,3 為 Table_B 特有。

常用的 JOIN

1、INNER JOIN

INNER JOIN 一般被譯作內連接。內連接查詢能將左表(表 A)和右表(表 B)中能關聯起來的數據連接后返回。

文氏圖:

INNER JOIN

 

示例查詢:

  1. SELECT A.PK AS A_PK, B.PK AS B_PK, 
  2.        A.Value AS A_Value, B.Value AS B_Value 
  3. FROM Table_A A 
  4. INNER JOIN Table_B B 
  5. ON A.PK = B.PK; 

查詢結果:

  1. +------+------+---------+---------+ 
  2. | A_PK | B_PK | A_Value | B_Value | 
  3. +------+------+---------+---------+ 
  4. |    1 |    1 | both ab | both ab | 
  5. +------+------+---------+---------+ 
  6. 1 row in set (0.00 sec) 

注:其中 A 為 Table_A 的別名,B 為 Table_B 的別名,下同。

2、LEFT JOIN

LEFT JOIN 一般被譯作左連接,也寫作 LEFT OUTER JOIN。左連接查詢會返回左表(表 A)中所有記錄,不管右表(表 B)中有沒有關聯的數據。在右表中找到的關聯數據列也會被一起返回。

文氏圖:

 


LEFT JOIN

 

 

示例查詢:

  1. SELECT A.PK AS A_PK, B.PK AS B_PK, 
  2.        A.Value AS A_Value, B.Value AS B_Value 
  3. FROM Table_A A 
  4. LEFT JOIN Table_B B 
  5. ON A.PK = B.PK; 

查詢結果:

  1. +------+------+---------+---------+ 
  2. | A_PK | B_PK | A_Value | B_Value | 
  3. +------+------+---------+---------+ 
  4. |    1 |    1 | both ab | both ba | 
  5. |    2 | NULL | only a  | NULL    | 
  6. +------+------+---------+---------+ 
  7. rows in set (0.00 sec) 

3、RIGHT JOIN

RIGHT JOIN 一般被譯作右連接,也寫作 RIGHT OUTER JOIN。右連接查詢會返回右表(表 B)中所有記錄,不管左表(表 A)中有沒有關聯的數據。在左表中找到的關聯數據列也會被一起返回。

文氏圖:

 


RIGHT JOIN

 

 

示例查詢:

  1. SELECT A.PK AS A_PK, B.PK AS B_PK, 
  2.        A.Value AS A_Value, B.Value AS B_Value 
  3. FROM Table_A A 
  4. RIGHT JOIN Table_B B 
  5. ON A.PK = B.PK; 

查詢結果:

  1. +------+------+---------+---------+ 
  2. | A_PK | B_PK | A_Value | B_Value | 
  3. +------+------+---------+---------+ 
  4. |    1 |    1 | both ab | both ba | 
  5. NULL |    3 | NULL    | only b  | 
  6. +------+------+---------+---------+ 
  7. rows in set (0.00 sec) 

4、FULL OUTER JOIN

FULL OUTER JOIN 一般被譯作外連接、全連接,實際查詢語句中可以寫作 FULL OUTER JOIN 或 FULL JOIN。外連接查詢能返回左右表里的所有記錄,其中左右表里能關聯起來的記錄被連接后返回。

文氏圖:

 


FULL OUTER JOIN

 

 

示例查詢:

  1. SELECT A.PK AS A_PK, B.PK AS B_PK, 
  2.        A.Value AS A_Value, B.Value AS B_Value 
  3. FROM Table_A A 
  4. FULL OUTER JOIN Table_B B 
  5. ON A.PK = B.PK; 

查詢結果:

  1. ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FULL OUTER JOIN Table_B B 
  2. ON A.PK = B.PK' at line 4 

注:我當前示例使用的 MySQL 不支持 FULL OUTER JOIN。

應當返回的結果(使用 UNION 模擬):

  1. mysql> SELECT * 
  2.     -> FROM Table_A 
  3.     -> LEFT JOIN Table_B 
  4.     -> ON Table_A.PK = Table_B.PK 
  5.     -> UNION ALL 
  6.     -> SELECT * 
  7.     -> FROM Table_A 
  8.     -> RIGHT JOIN Table_B 
  9.     -> ON Table_A.PK = Table_B.PK 
  10.     -> WHERE Table_A.PK IS NULL
  11. +------+---------+------+---------+ 
  12. | PK   | Value   | PK   | Value   | 
  13. +------+---------+------+---------+ 
  14. |    1 | both ab |    1 | both ba | 
  15. |    2 | only a  | NULL | NULL    | 
  16. NULL | NULL    |    3 | only b  | 
  17. +------+---------+------+---------+ 
  18. rows in set (0.00 sec) 

小結

以上四種,就是 SQL 里常見 JOIN 的種類和概念了,看一下它們的合影:

小結

 

有沒有感覺少了些什么,學數學集合時完全不止這幾種情況?確實如此,繼續看。

延伸用法

1、LEFT JOIN EXCLUDING INNER JOIN

返回左表有但右表沒有關聯數據的記錄集。

文氏圖:

 


LEFT JOIN EXCLUDING INNER JOIN

 

 

示例查詢:

  1. SELECT A.PK AS A_PK, B.PK AS B_PK, 
  2.        A.Value AS A_Value, B.Value AS B_Value 
  3. FROM Table_A A 
  4. LEFT JOIN Table_B B 
  5. ON A.PK = B.PK 
  6. WHERE B.PK IS NULL

查詢結果:

  1. +------+------+---------+---------+ 
  2. | A_PK | B_PK | A_Value | B_Value | 
  3. +------+------+---------+---------+ 
  4. |    2 | NULL | only a  | NULL    | 
  5. +------+------+---------+---------+ 
  6. 1 row in set (0.01 sec) 

2、RIGHT JOIN EXCLUDING INNER JOIN

返回右表有但左表沒有關聯數據的記錄集。

文氏圖:


RIGHT JOIN EXCLUDING INNER JOIN

 

 

 

示例查詢:

  1. SELECT A.PK AS A_PK, B.PK AS B_PK, 
  2.        A.Value AS A_Value, B.Value AS B_Value 
  3. FROM Table_A A 
  4. RIGHT JOIN Table_B B 
  5. ON A.PK = B.PK 
  6. WHERE A.PK IS NULL

查詢結果:

  1. +------+------+---------+---------+ 
  2. | A_PK | B_PK | A_Value | B_Value | 
  3. +------+------+---------+---------+ 
  4. NULL |    3 | NULL    | only b  | 
  5. +------+------+---------+---------+ 
  6. 1 row in set (0.00 sec) 

3、FULL OUTER JOIN EXCLUDING INNER JOIN

返回左表和右表里沒有相互關聯的記錄集。

文氏圖:

 

 


FULL OUTER JOIN EXCLUDING INNER JOIN

 

 

 

示例查詢:

  1. SELECT A.PK AS A_PK, B.PK AS B_PK, 
  2.        A.Value AS A_Value, B.Value AS B_Value 
  3. FROM Table_A A 
  4. FULL OUTER JOIN Table_B B 
  5. ON A.PK = B.PK 
  6. WHERE A.PK IS NULL 
  7. OR B.PK IS NULL

因為使用到了 FULL OUTER JOIN,MySQL 在執行該查詢時再次報錯。

  1. ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FULL OUTER JOIN Table_B B 
  2. ON A.PK = B.PK 
  3. WHERE A.PK IS NULL 
  4. OR B.PK IS NULLat line 4 

應當返回的結果(用 UNION 模擬):

  1. mysql> SELECT * 
  2.     -> FROM Table_A 
  3.     -> LEFT JOIN Table_B 
  4.     -> ON Table_A.PK = Table_B.PK 
  5.     -> WHERE Table_B.PK IS NULL 
  6.     -> UNION ALL 
  7.     -> SELECT * 
  8.     -> FROM Table_A 
  9.     -> RIGHT JOIN Table_B 
  10.     -> ON Table_A.PK = Table_B.PK 
  11.     -> WHERE Table_A.PK IS NULL
  12. +------+--------+------+--------+ 
  13. | PK   | Value  | PK   | Value  | 
  14. +------+--------+------+--------+ 
  15. |    2 | only a | NULL | NULL   | 
  16. NULL | NULL   |    3 | only b | 
  17. +------+--------+------+--------+ 
  18. rows in set (0.00 sec) 

總結

以上七種用法基本上可以覆蓋各種 JOIN 查詢了。七種用法的全家福:

 

看著它們,我仿佛回到了當年學數學,求交集并集的時代……

順帶張貼一下 C.L. Moffatt 帶 SQL 語句的圖片,配合學習,風味更佳:

 

更多的 JOIN

除以上幾種外,還有更多的 JOIN 用法,比如 CROSS JOIN(迪卡爾集)、SELF JOIN,可以參考 SQL JOINS Slide Presentation 學習。

1、CROSS JOIN

返回左表與右表之間符合條件的記錄的迪卡爾集。

圖示:

 

示例查詢:

  1. SELECT A.PK AS A_PK, B.PK AS B_PK, 
  2.        A.Value AS A_Value, B.Value AS B_Value 
  3. FROM Table_A A 
  4. CROSS JOIN Table_B B; 

查詢結果:

  1. +------+------+---------+---------+ 
  2. | A_PK | B_PK | A_Value | B_Value | 
  3. +------+------+---------+---------+ 
  4. |    1 |    1 | both ab | both ba | 
  5. |    2 |    1 | only a  | both ba | 
  6. |    1 |    3 | both ab | only b  | 
  7. |    2 |    3 | only a  | only b  | 
  8. +------+------+---------+---------+ 
  9. rows in set (0.00 sec) 

上面講過的幾種 JOIN 查詢的結果都可以用 CROSS JOIN 加條件模擬出來,比如 INNER JOIN 對應 CROSS JOIN ... WHERE A.PK = B.PK。

2、SELF JOIN

返回表與自己連接后符合條件的記錄,一般用在表里有一個字段是用主鍵作為外鍵的情況。

比如 Table_C 的結構與數據如下:

  1. +--------+----------+-------------+ 
  2. | EMP_ID | EMP_NAME | EMP_SUPV_ID | 
  3. +--------+----------+-------------+ 
  4. |   1001 | Ma       |        NULL | 
  5. |   1002 | Zhuang   |        1001 | 
  6. +--------+----------+-------------+ 
  7. rows in set (0.00 sec) 

EMP_ID 字段表示員工 ID,EMP_NAME 字段表示員工姓名,EMP_SUPV_ID 表示主管 ID。

示例查詢:

現在我們想查詢所有有主管的員工及其對應的主管 ID 和姓名,就可以用 SELF JOIN 來實現。

  1. SELECT A.EMP_ID AS EMP_ID, A.EMP_NAME AS EMP_NAME, 
  2.     B.EMP_ID AS EMP_SUPV_ID, B.EMP_NAME AS EMP_SUPV_NAME 
  3. FROM Table_C A, Table_C B 
  4. WHERE A.EMP_SUPV_ID = B.EMP_ID; 

查詢結果:

  1. +--------+----------+-------------+---------------+ 
  2. | EMP_ID | EMP_NAME | EMP_SUPV_ID | EMP_SUPV_NAME | 
  3. +--------+----------+-------------+---------------+ 
  4. |   1002 | Zhuang   |        1001 | Ma            | 
  5. +--------+----------+-------------+---------------+ 
  6. 1 row in set (0.00 sec) 

 

責任編輯:武曉燕 來源: mazhuang
相關推薦

2020-10-09 09:49:18

HTTPS網絡 HTTP

2021-05-10 08:34:37

USB接口USB網絡設備

2019-11-13 10:31:49

Kafka架構高可用

2022-02-22 08:25:51

typeScript泛型概念泛型使用

2019-04-16 15:18:28

SQLJOIN數據庫

2021-05-28 11:54:29

MySQL數據庫主從復制

2021-09-06 07:58:47

鏈表數據結構

2022-03-27 09:06:25

vuexActionsMutations

2020-06-18 10:48:44

Linux 系統 數據

2010-05-21 17:30:28

2019-03-18 15:00:48

SQLJoin用法數據庫

2018-02-25 22:37:34

2023-12-01 08:39:29

分布式鎖系統

2020-11-04 08:37:37

C語言C++內存

2017-08-09 15:07:08

大數據數據分析戶畫像

2021-06-16 00:57:16

JVM加載機制

2021-12-06 10:22:47

切片拷貝Python

2025-06-19 10:00:00

數據庫MySQL日志

2010-01-21 17:15:22

可網管交換機

2023-08-09 09:03:49

CPU密集型運算
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文字幕精品一区久久久久 | 天天天操操操 | 精品国产乱码久久久久久图片 | 九九九久久国产免费 | 嫩草最新网址 | 91精品一区 | 国产有码 | 一区观看 | 九九激情视频 | 欧美激情一区二区三区 | 97精品国产97久久久久久免费 | 久久国内精品 | 午夜无码国产理论在线 | 久久精品亚洲精品国产欧美 | 在线视频国产一区 | av中文天堂 | 男女久久久 | 国产精品视频在线播放 | www.久久| 美日韩免费 | 日韩在线一区二区 | 久久av网| 免费观看羞羞视频网站 | 97色在线视频 | 毛片日韩| 亚洲电影在线播放 | 视频一二三区 | 视频在线观看亚洲 | 老头搡老女人毛片视频在线看 | 97精品超碰一区二区三区 | 天天爽网站 | 成人二区 | 欧美老妇交乱视频 | 久久久精品日本 | 91精品国产91久久久久青草 | 中文字幕第一页在线 | 久久精点视频 | 日韩在线一区二区三区 | 久久免费福利 | 久久成人精品视频 | aa级毛片毛片免费观看久 |