sql join on和不用join区别_图解 SQL 各种 JOIN,太有用了!
前言
在各种问答社区里谈及 SQL 里的各种 JOIN 之间的区别时,最被广为引用的是 CodeProject 上 C.L. Moffatt 的文章 Visual Representation of SQL Joins,他确实讲得简单明了,使用文氏图来帮助理解,效果明显。本文将沿用他的讲解方式,稍有演绎,可以视为该文较为粗糙的中译版。
约定
下文将使用两个数据库表 Table_A 和 Table_B 来进行示例讲解,其结构与数据分别如下:mysql> SELECT * FROM Table_A ORDER BY PK ASC;
+----+---------+
| PK | Value |
+----+---------+
| 1 | both ab |
| 2 | only a |
+----+---------+
2 rows in set (0.00 sec)
mysql> SELECT * from Table_B ORDER BY PK ASC;
其中 PK 为 1 的记录在 Table_A 和 Table_B 中都有,2 为 Table_A 特有,3 为 Table_B 特有。
+----+---------+
| PK | Value |
+----+---------+
| 1 | both ab |
| 3 | only b |
+----+---------+
2 rows in set (0.00 sec)
常用的 JOIN
1、INNER JOIN
INNER JOIN 一般被译作内连接。内连接查询能将左表(表 A)和右表(表 B)中能关联起来的数据连接后返回。文氏图:INNER JOIN示例查询:SELECT A.PK AS A_PK, B.PK AS B_PK,
A.Value AS A_Value, B.Value AS B_Value
FROM Table_A A
INNER JOIN Table_B B
ON A.PK = B.PK;
查询结果:
+------+------+---------+---------+
注:其中 A 为 Table_A 的别名,B 为 Table_B 的别名,下同。2、LEFT JOINLEFT JOIN 一般被译作左连接,也写作 LEFT OUTER JOIN。左连接查询会返回左表(表 A)中所有记录,不管右表(表 B)中有没有关联的数据。在右表中找到的关联数据列也会被一起返回。文氏图:LEFT JOIN示例查询:
| A_PK | B_PK | A_Value | B_Value |
+------+------+---------+---------+
| 1 | 1 | both ab | both ab |
+------+------+---------+---------+
1 row in set (0.00 sec)SELECT A.PK AS A_PK, B.PK AS B_PK,
A.Value AS A_Value, B.Value AS B_Value
FROM Table_A A
LEFT JOIN Table_B B
ON A.PK = B.PK;
查询结果:
+------+------+---------+---------+
| A_PK | B_PK | A_Value | B_Value |
+------+------+---------+---------+
| 1 | 1 | both ab | both ba |
| 2 | NULL | only a | NULL |
+------+------+---------+---------+
2 rows in set (0.00 sec)
3、RIGHT JOIN
RIGHT JOIN 一般被译作右连接,也写作 RIGHT OUTER JOIN。右连接查询会返回右表(表 B)中所有记录,不管左表(表 A)中有没有关联的数据。在左表中找到的关联数据列也会被一起返回。文氏图:RIGHT JOIN示例查询:SELECT A.PK AS A_PK, B.PK AS B_PK,
A.Value AS A_Value, B.Value AS B_Value
FROM Table_A A
RIGHT JOIN Table_B B
ON A.PK = B.PK;
查询结果:
+------+------+---------+---------+
| A_PK | B_PK | A_Value | B_Value |
+------+------+---------+---------+
| 1 | 1 | both ab | both ba |
| NULL | 3 | NULL | only b |
+------+------+---------+---------+
2 rows in set (0.00 sec)
4、FULL OUTER JOIN
FULL OUTER JOIN 一般被译作外连接、全连接,实际查询语句中可以写作 FULL OUTER JOIN 或 FULL JOIN。外连接查询能返回左右表里的所有记录,其中左右表里能关联起来的记录被连接后返回。文氏图:FULL OUTER JOIN示例查询:SELECT A.PK AS A_PK, B.PK AS B_PK,
A.Value AS A_Value, B.Value AS B_Value
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.PK = B.PK;
查询结果:
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
注:我当前示例使用的 MySQL 不支持 FULL OUTER JOIN。应当返回的结果(使用 UNION 模拟):
ON A.PK = B.PK' at line 4mysql> SELECT *
-> FROM Table_A
-> LEFT JOIN Table_B
-> ON Table_A.PK = Table_B.PK
-> UNION ALL
-> SELECT *
-> FROM Table_A
-> RIGHT JOIN Table_B
-> ON Table_A.PK = Table_B.PK
-> WHERE Table_A.PK IS NULL;
+------+---------+------+---------+
| PK | Value | PK | Value |
+------+---------+------+---------+
| 1 | both ab | 1 | both ba |
| 2 | only a | NULL | NULL |
| NULL | NULL | 3 | only b |
+------+---------+------+---------+
3 rows in set (0.00 sec)
小结
以上四种,就是 SQL 里常见 JOIN 的种类和概念了,看一下它们的合影:小结有没有感觉少了些什么,学数学集合时完全不止这几种情况?确实如此,继续看。
延伸用法
1、LEFT JOIN EXCLUDING INNER JOIN
返回左表有但右表没有关联数据的记录集。文氏图:LEFT JOIN EXCLUDING INNER JOIN示例查询:SELECT A.PK AS A_PK, B.PK AS B_PK,
查询结果:
A.Value AS A_Value, B.Value AS B_Value
FROM Table_A A
LEFT JOIN Table_B B
ON A.PK = B.PK
WHERE B.PK IS NULL;+------+------+---------+---------+
| A_PK | B_PK | A_Value | B_Value |
+------+------+---------+---------+
| 2 | NULL | only a | NULL |
+------+------+---------+---------+
1 row in set (0.01 sec)
2、RIGHT JOIN EXCLUDING INNER JOIN
返回右表有但左表没有关联数据的记录集。文氏图:RIGHT JOIN EXCLUDING INNER JOIN示例查询:SELECT A.PK AS A_PK, B.PK AS B_PK,
A.Value AS A_Value, B.Value AS B_Value
FROM Table_A A
RIGHT JOIN Table_B B
ON A.PK = B.PK
WHERE A.PK IS NULL;
查询结果:
+------+------+---------+---------+
| A_PK | B_PK | A_Value | B_Value |
+------+------+---------+---------+
| NULL | 3 | NULL | only b |
+------+------+---------+---------+
1 row in set (0.00 sec)
3、FULL OUTER JOIN EXCLUDING INNER JOIN
返回左表和右表里没有相互关联的记录集。文氏图:FULL OUTER JOIN EXCLUDING INNER JOIN示例查询:SELECT A.PK AS A_PK, B.PK AS B_PK,
A.Value AS A_Value, B.Value AS B_Value
FROM Table_A A
FULL OUTER JOIN Table_B B
ON A.PK = B.PK
WHERE A.PK IS NULL
OR B.PK IS NULL;
因为使用到了 FULL OUTER JOIN,MySQL 在执行该查询时再次报错。
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
ON A.PK = B.PK
WHERE A.PK IS NULL
OR B.PK IS NULL' at line 4
应当返回的结果(用 UNION 模拟):
mysql> SELECT *
-> FROM Table_A
-> LEFT JOIN Table_B
-> ON Table_A.PK = Table_B.PK
-> WHERE Table_B.PK IS NULL
-> UNION ALL
-> SELECT *
-> FROM Table_A
-> RIGHT JOIN Table_B
-> ON Table_A.PK = Table_B.PK
-> WHERE Table_A.PK IS NULL;
+------+--------+------+--------+
| PK | Value | PK | Value |
+------+--------+------+--------+
| 2 | only a | NULL | NULL |
| NULL | NULL | 3 | only b |
+------+--------+------+--------+
2 rows in set (0.00 sec)
总结
以上七种用法基本上可以覆盖各种 JOIN 查询了。七种用法的全家福:看着它们,我仿佛回到了当年学数学,求交集并集的时代……顺带张贴一下 C.L. Moffatt 带 SQL 语句的图片,配合学习,风味更佳:
更多的 JOIN
除以上几种外,还有更多的 JOIN 用法,比如 CROSS JOIN(迪卡尔集)、SELF JOIN,可以参考 SQL JOINS Slide Presentation 学习。
1、CROSS JOIN
返回左表与右表之间符合条件的记录的迪卡尔集。图示:示例查询:SELECT A.PK AS A_PK, B.PK AS B_PK,
A.Value AS A_Value, B.Value AS B_Value
FROM Table_A A
CROSS JOIN Table_B B;
查询结果:
+------+------+---------+---------+
上面讲过的几种 JOIN 查询的结果都可以用 CROSS JOIN 加条件模拟出来,比如 INNER JOIN 对应 CROSS JOIN ... WHERE A.PK = B.PK。
| A_PK | B_PK | A_Value | B_Value |
+------+------+---------+---------+
| 1 | 1 | both ab | both ba |
| 2 | 1 | only a | both ba |
| 1 | 3 | both ab | only b |
| 2 | 3 | only a | only b |
+------+------+---------+---------+
4 rows in set (0.00 sec)
2、SELF JOIN
返回表与自己连接后符合条件的记录,一般用在表里有一个字段是用主键作为外键的情况。比如 Table_C 的结构与数据如下:+--------+----------+-------------+
EMP_ID 字段表示员工 ID,EMP_NAME 字段表示员工姓名,EMP_SUPV_ID 表示主管 ID。示例查询:现在我们想查询所有有主管的员工及其对应的主管 ID 和姓名,就可以用 SELF JOIN 来实现。
| EMP_ID | EMP_NAME | EMP_SUPV_ID |
+--------+----------+-------------+
| 1001 | Ma | NULL |
| 1002 | Zhuang | 1001 |
+--------+----------+-------------+
2 rows in set (0.00 sec)SELECT A.EMP_ID AS EMP_ID, A.EMP_NAME AS EMP_NAME,
查询结果:
B.EMP_ID AS EMP_SUPV_ID, B.EMP_NAME AS EMP_SUPV_NAME
FROM Table_C A, Table_C B
WHERE A.EMP_SUPV_ID = B.EMP_ID;+--------+----------+-------------+---------------+
| EMP_ID | EMP_NAME | EMP_SUPV_ID | EMP_SUPV_NAME |
+--------+----------+-------------+---------------+
| 1002 | Zhuang | 1001 | Ma |
+--------+----------+-------------+---------------+
1 row in set (0.00 sec)
作者:码志 链接:https://mazhuang.org/2017/09/11/joins-in-sql/
推荐阅读
华为 Java 开发编程军规,谁违反谁走
厉害了,小姐姐用动图展示 10 大 Git 命令!
Linux 最常用命令整理,建议收藏!
再见,Navicat!IDEA 这个兄弟,真香!
Redis 6.0 这个新特性真牛逼!
为什么老外不愿意用 MyBatis?
IDEA 实用小技巧,Mark起来!
扫码关注小姐姐学Java
最近小姐姐在面试,整理了一份《Java面试通关手册》,覆盖了JVM、多线程、SSM、Redis、MySQL、微服务、算法、数据结构等等。获取方式:点“在看”,关注公众号回复 666 领取。
sql join on和不用join区别_图解 SQL 各种 JOIN,太有用了!相关推荐
- left join 临时表_图解SQL的JOIN
对于SQL的Join,在学习起来可能是比较乱的.我们知道,SQL的Join语法有很多inner的,有outer的,有left的,有时候,对于Select出来的结果集是什么样子有点不是很清楚.Codin ...
- sql left join用法_图解 SQL 中 JOIN 的各种用法
点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 作者:CodingStar cnblogs.com/BoyceYang/p/3145279 ...
- python和java还有sql区别_为什么SQL聚合函数比Python和Java(或Poor Man的OLAP)慢得多,
Postgres做得比看起来好多了(保持数据一致性开始!) 如果值不必是100%,或者如果表很少更新,但是您经常运行此计算,则可能需要查看物化视图以加速. (注意,我没有在Postgres使用物化视图 ...
- sql 复合主键 联合主键_学习SQL:主键
sql 复合主键 联合主键 If you've already worked with databases, then you could hardly miss the term – Primary ...
- sql中聚合函数和分组函数_学习SQL:聚合函数
sql中聚合函数和分组函数 SQL has many cool features and aggregate functions are definitely one of these feature ...
- inner join on 加条件和where加条件_图解 SQL 中各种连接 JOIN
先用文字来捋一下思路,数据库操作中无非就是「 增删查改 」,其中「 查」用得最多且最复杂,变化多端.查询的时候,我们可以只是单表查询,也可以是多表连接查询,单表查询中的学问也很大,但限于篇幅,本次主要 ...
- mysql版本链图解_图解 SQL 中各种连接 JOIN
先用文字来捋一下思路,数据库操作中无非就是「增删查改」,其中「 查」用得最多且最复杂,变化多端.查询的时候,我们可以只是单表查询,也可以是多表连接查询,单表查询中的学问也很大,但限于篇幅,本次主要分享 ...
- sql数据库和mysql有什么区别_【数据库】MySQL和sql的区别有哪些 - 收获啦
sql是什么? sql,全称:结构化查询语言(Structured Query Language),是一种用于操作数据库的语言,它是用于所有数据库的基本语言.虽然,不同数据库之间存在较小的语法更改,但 ...
- sql如何遍历几百万的表_关于SQL查询效率,100w数据,查询只要1秒
1.关于SQL查询效率,100w数据,查询只要1秒,与您分享: 机器情况 p4: 2.4 内存: 1 G os: windows 2003 数据库: ms sql server 2000 目的: 查询 ...
最新文章
- R语言使用integrate函数进行函数积分计算实战
- 《开源者说》08期:聊聊Java那些事儿
- 基于托管C++的增删改查及异步回调小程序
- 中医药可投期刊推荐-24本-2021版
- flume使用telnet作为入口出现connection refused
- 1026 程序运行时间 (15 分)
- 单片机启动流程(以STM32为例)
- python实现希尔排序(已编程实现)
- Android中使用sax解析XML
- oracle alter和 insert,Oracle 笔记一 select insert update delete transaction create alter
- IOS 腾讯微博开放平台 SDK 初体验
- SAP中常用SE系列TCODE汇总
- 小米android6.01 root,小米 小米6(安卓8.0)获取Root权限服务含精简系统方案
- 营销自动化权威指南_任务自动化指南
- 低碳环保+变废为宝=马铃薯淀粉生产废水处理设备
- 虚拟化arm服务器,arm服务器虚拟化(armvm虚拟化搭建手机)
- NLP自然语言处理之情感分析分析讲解、知识构建
- 为什么访问亚马逊的网站卡顿?
- 开发购物商城app系统软件需要多少钱
- 沐圣moolsun:做真正的民族品牌
热门文章
- C++ 内存模型——虚表(vtbl)的访问
- java.util —— 工具类
- [面试]——用一行代码判断两矩形是否相交
- 算法直观与对模型的理解
- 假设检验——抽样调查的结论依赖于样本量的大小
- Java知识点汇总以及常见面试题
- python入门指南-python3.6.0入门指南(官方版).pdf
- python在哪里写代码-python的代码在哪编写
- python是什么类型的语言-为什么说 Python 是强类型语言?
- 深度学习笔记 | 第16讲:语音识别——一份简短的技术综述