偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

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

數(shù)據(jù)庫 MySQL
從業(yè)以來主要在做客戶端,用到的數(shù)據(jù)庫都是表結(jié)構(gòu)比較簡單的 SQLite,以我那還給老師一大半的 SQL 水平倒也能對付。

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

 

[[274993]]

前言

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

約定

下文將使用兩個數(shù)據(jù)庫表 Table_A 和 Table_B 來進行示例講解,其結(jié)構(gòu)與數(shù)據(jù)分別如下:

  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 一般被譯作內(nèi)連接。內(nèi)連接查詢能將左表(表 A)和右表(表 B)中能關(guān)聯(lián)起來的數(shù)據(jù)連接后返回。

文氏圖:

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; 

查詢結(jié)果:

  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)中有沒有關(guān)聯(lián)的數(shù)據(jù)。在右表中找到的關(guān)聯(lián)數(shù)據(jù)列也會被一起返回。

文氏圖:

 


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; 

查詢結(jié)果:

  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)中有沒有關(guān)聯(lián)的數(shù)據(jù)。在左表中找到的關(guān)聯(lián)數(shù)據(jù)列也會被一起返回。

文氏圖:

 


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; 

查詢結(jié)果:

  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。外連接查詢能返回左右表里的所有記錄,其中左右表里能關(guān)聯(lián)起來的記錄被連接后返回。

文氏圖:

 


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; 

查詢結(jié)果:

  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 

注:我當(dāng)前示例使用的 MySQL 不支持 FULL OUTER JOIN。

應(yīng)當(dāng)返回的結(jié)果(使用 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) 

小結(jié)

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

小結(jié)

 

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

延伸用法

1、LEFT JOIN EXCLUDING INNER JOIN

返回左表有但右表沒有關(guān)聯(lián)數(shù)據(jù)的記錄集。

文氏圖:

 


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

查詢結(jié)果:

  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

返回右表有但左表沒有關(guān)聯(lián)數(shù)據(jù)的記錄集。

文氏圖:


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

查詢結(jié)果:

  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

返回左表和右表里沒有相互關(guān)聯(lián)的記錄集。

文氏圖:

 

 


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 在執(zhí)行該查詢時再次報錯。

  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 

應(yīng)當(dāng)返回的結(jié)果(用 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) 

總結(jié)

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

 

看著它們,我仿佛回到了當(dāng)年學(xué)數(shù)學(xué),求交集并集的時代……

順帶張貼一下 C.L. Moffatt 帶 SQL 語句的圖片,配合學(xué)習(xí),風(fēng)味更佳:

 

更多的 JOIN

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

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; 

查詢結(jié)果:

  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 查詢的結(jié)果都可以用 CROSS JOIN 加條件模擬出來,比如 INNER JOIN 對應(yīng) CROSS JOIN ... WHERE A.PK = B.PK。

2、SELF JOIN

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

比如 Table_C 的結(jié)構(gòu)與數(shù)據(jù)如下:

  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。

示例查詢:

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

  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; 

查詢結(jié)果:

  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) 

 

責(zé)任編輯:武曉燕 來源: mazhuang
相關(guān)推薦

2020-10-09 09:49:18

HTTPS網(wǎng)絡(luò) HTTP

2021-05-10 08:34:37

USB接口USB網(wǎng)絡(luò)設(shè)備

2022-02-22 08:25:51

typeScript泛型概念泛型使用

2019-11-13 10:31:49

Kafka架構(gòu)高可用

2019-04-16 15:18:28

SQLJOIN數(shù)據(jù)庫

2021-09-06 07:58:47

鏈表數(shù)據(jù)結(jié)構(gòu)

2021-05-28 11:54:29

MySQL數(shù)據(jù)庫主從復(fù)制

2022-03-27 09:06:25

vuexActionsMutations

2020-06-18 10:48:44

Linux 系統(tǒng) 數(shù)據(jù)

2010-05-21 17:30:28

2018-02-25 22:37:34

2019-03-18 15:00:48

SQLJoin用法數(shù)據(jù)庫

2023-12-01 08:39:29

分布式鎖系統(tǒng)

2020-11-04 08:37:37

C語言C++內(nèi)存

2017-08-09 15:07:08

大數(shù)據(jù)數(shù)據(jù)分析戶畫像

2021-06-16 00:57:16

JVM加載機制

2021-12-06 10:22:47

切片拷貝Python

2025-06-19 10:00:00

數(shù)據(jù)庫MySQL日志

2010-01-21 17:15:22

可網(wǎng)管交換機

2023-08-09 09:03:49

CPU密集型運算
點贊
收藏

51CTO技術(shù)棧公眾號