本文转载至https://mazhuang.org/2017/09/11/joins-in-sql/#full-outer-join-excluding-inner-join,如需阅读原文请至上述链接去往,原作者有更多关于数据库相关文章,写的不错,推荐一下!

下文将使用两个数据库表 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. 2 rows in set (0.00 sec)
  9. mysql> SELECT * from Table_B ORDER BY PK ASC;
  10. +----+---------+
  11. | PK | Value |
  12. +----+---------+
  13. | 1 | both ab |
  14. | 3 | only b |
  15. +----+---------+
  16. 2 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)中能关联起来的数据连接后返回。

文氏图:



示例查询:

  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)中有没有关联的数据。在右表中找到的关联数据列也会被一起返回。

文氏图:



示例查询:

  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. 2 rows in set (0.00 sec)

3、RIGHT JOIN

RIGHT JOIN 一般被译作右连接,也写作 RIGHT OUTER JOIN。右连接查询会返回右表(表 B)中所有记录,不管左表(表 A)中有没有关联的数据。在左表中找到的关联数据列也会被一起返回。

文氏图:



示例查询:

  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. 2 rows in set (0.00 sec)

4、FULL OUTER JOIN

FULL OUTER JOIN 一般被译作外连接、全连接,实际查询语句中可以写作 FULL OUTER JOIN 或 FULL 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. 3 rows in set (0.00 sec)

小结

以上四种,就是 SQL 里常见 JOIN 的种类和概念了,看一下它们的合影:

延伸用法

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

返回右表有但左表没有关联数据的记录集。

文氏图:



示例查询:

  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

返回左表和右表里没有相互关联的记录集。

文氏图:



示例查询:

  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 NULL' at 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. 2 rows in set (0.00 sec)

总结

以上七种用法基本上可以覆盖各种 JOIN 查询了。七种用法的全家福:



补充说明

文中的图使用 Keynote 绘制;

个人的体会是 SQL 里的 JOIN 查询与数学里的求交集、并集等很像;

SQLite 不支持 RIGHT JOIN 和 FULL OUTER JOIN,可以使用 LEFT JOIN 和 UNION 来达到相同的效果;

MySQL 不支持 FULL OUTER JOIN,可以使用 LEFT JOIN 和 UNION 来达到相同的效果;

图解数据库中的各种 JOIN的更多相关文章

  1. 图解数据库中的join操作

    1.所有的join都从cross join衍生而来 2.所有join图示 转自Say NO to Venn Diagrams When Explaining JOINs

  2. 带你了解数据库中JOIN的用法

    前言 欢迎关注公众号:Coder编程 获取最新原创技术文章和相关免费学习资料,随时随地学习技术知识! 本章主要介绍数据库中Join的的用法,也是我们在使用数据库时非常基础的一个知识点.本次会介绍数据库 ...

  3. 图解如何 将Excel里的数据导入到sql server数据库中

    项目中,经常会碰到如何将Excel里的数据导入到sql server中的问题. 下面,图解如何实现导入Excel中的数据到sql server 2008 R2: Excel截图如下: 查询pub数据库 ...

  4. 【转】图解SQL的各种连接join

    原帖地址:http://www.nowamagic.net/librarys/veda/detail/936 图解SQL的各种连接join 让你对SQL的连接一目了然 在 2011年12月22日 那天 ...

  5. 在SQL2008查找某数据库中的列是否存在某个值

    在SQL2008查找某数据库中的列是否存在某个值 --SQL2008查找某数据库中的列是否存在某个值 create proc spFind_Column_In_DB ( @type int,--类型: ...

  6. SQL Server 在多个数据库中创建同一个存储过程(Create Same Stored Procedure in All Databases)

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 遇到的问题(Problems) 实现代码(SQL Codes) 方法一:拼接SQL: 方法二: ...

  7. SQLSERVER如何获取一个数据库中的所有表的名称、一个表中所有字段的名称

    1.查询数据库中的所有数据库名: SELECT Name FROM Master..SysDatabases ORDER BY Name 2.查询某个数据库中所有的表名: SELECT Name FR ...

  8. sql搜索数据库中具有某列的表

    在接口中明明有某个节点,但在数据库中却找不到,为此本人写了一个sql,以供快速查找. Select distinct syscolumns.name,sysobjects.name from sysc ...

  9. SQL查询数据库中所有指定类型的字段名称和所在的表名

    --查询数据库中所有指定类型的字段名称和所在的表名 --eg: 下面查的是当前数据库中 所有字段类型为 nvarchar(max) 的字段名和表名 SELECT cols.object_id , co ...

随机推荐

  1. MFC BASE64加解密 算法

    unsigned char * base64 = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ...

  2. 【C# 开发技巧】在VS程序如何取消.vshost的进程

    我们在双击执行一个EXE程序,会有两个进程,程序关闭之后,貌似只能关闭你的程序,附加的vshost.exe仍然存在.如下图 解决方案: 1.在调试页面,改成release,同时取消最后一项启用承载进程 ...

  3. 《C语言程序设计》学习笔记(二)

    第八章 函数 函数的基本概念 定义:函数由函数名.参数和函数体组成. 函数定义的一般形式: 类型说明符 函数名(形式参数声明) { [说明与定义部分] 语句: } 说明: 1.类型说明符用来说明函数的 ...

  4. 经典PID控制及应用体会总结

    经典PID控制及应用体会总结 PID控制原理 PID是一种线性控制器,它根据给定值rin(t)与实际输出值yout(t)构成控制方案: 重点关注相关算法是如何对偏差进行处理的: PID控制器各校正环节 ...

  5. c#窗体程序绘制简单心形

    分析思路: 两个圆形和一个矩形如图叠加再逆时针旋转45°,就能得到一个极其简陋的心. 我们只需要将圆心放在矩形上边中点和右边中点即可. 代码如下:   private void button1_Cli ...

  6. execl文件读取封装

    前言:做自动化常用的公共方法 注:第一次使用记得先 pip install xlrd 模块import xlrd class ReadExecl(): def __init__(self,filena ...

  7. 基于SymmetricDS的多主一从数据库同步方案

    原文参照:https://blog.csdn.net/seattle0564/article/details/22096901 下面就记录下测试的一款第三方同步方案SymmetricDS(以下简称S) ...

  8. 我叫Tomcat:一款web服务器

    我叫Tomcat:一款web服务器 如何将我们的 Java 代码,运行在网络上,初学时,首先接触到的一般都是Servlet以及Jsp(或略过Jsp)而 Tomcat 就是这两者的容器,帮你处理动态网页 ...

  9. React学习,搭建项目,入门

    react项目基于node.js.用npm包管理工具; 在cmd命令行中输入: npm install -g create-react-app 等待其安装,意思是全局安装create-react-ap ...

  10. final关键字、多态 (札记)

    目录 protected fianl 子父类中同名的 private 方法 java中的前期绑定 免疫多态 谁先被执行,构造器 还是 初始化? 协变返回类型 <Thinking in java& ...