SQL JOIN 的使用
由于工作需要,现在也开始写一些复杂一点的 sql 了。由于之前对于 join
与 where
关键字的使用一直有疑惑,故写一篇文章整理一下,算是对 sql 中各种表联结使用的一个总结。
SQL JOIN 的作用
sql 关键字 union
与 intersect
属于以行方向为单位的集合运算,进行这些集合运算时,会导致记录行数的增加或减少。
关键字 join
则是属于列方向的运算,将其他表中的列添加过来。我们称这种操作为联结。
sql 联结根据其用途可以分为多种,这里主要讲述内联结与外联结。
INNER JOIN
内联结,inner join,是使用最广泛的联结运算。我们以例子来说明内联结的含义。
student
表结构与记录以下:
student_id | student_name |
---|---|
1 | Leo |
2 | Lee |
3 | Hao |
score
表结构与记录以下:
student_id | student_score |
---|---|
1 | 89 |
2 | 95 |
可以看到 student_id
列存在于 student
表和 score
表,其他列则只存在于一张表。可以将 student_id
列作为桥梁,将两表满足同样条件的列汇集到同一结果之中,这就是联结运算。
可以看到,学生 Leo 的 id 为 1,分数在 score
表,Leo 的分数为 89 分。学生 Lee 的 id 为 2,分数为 95。学生 Hao 的 id 为 3,但 score
表中没有 Hao 的分数。
使用 inner join
对 student
表和 score
表进行联结,sql 以下所示:
select st.student_id, st.student_name, sc.student_score
from student stinner join score sc on st.student_id = sc.student_id;
执行 sql 结果如下所示。
student_id | student_name | student_score |
---|---|---|
1 | Leo | 89 |
2 | Lee | 95 |
关于 inner join
的使用,有几点需要注意的。
- from 子句
from
子句使用 inner join
,将两张表联结起来。
- on 子句
on
子句是联结的条件,例如我们使用 student_id
作为联结条件:
on st.student_id = sc.student_id
- select 子句
select
子句用于指定提取哪些列。
- 与 where 子句结合
如果我们只想看查 student_id
为 1 的情况,可以继续使用 where
子句。
select st.student_id, st.student_name, sc.student_score
from student stinner join score sc on st.student_id = SC.student_id
where st.student_id = 1;
执行结果以下:
student_id | student_name | student_score |
---|---|---|
1 | Leo | 89 |
OUTER JOIN
外联结,outer join,与内联结一样,也是通过 on
子句将两张表联结起来,只是结果有所不同。
为了说明外联结与内联结的不同,我们将上面内联结的例子转换成外联结,看下执行结果。
select st.student_id, st.student_name, sc.student_score
from student stleft outer join score sc on st.student_id = sc.student_id;
执行结果如下表所示:
student_id | student_name | student_score |
---|---|---|
1 | Leo | 89 |
2 | Lee | 95 |
3 | Hao |
- 外联结选取出单张表全部记录
与内联结相比,外联结的不同点在于结果的行数不一样。内联结执行结果有 2 条记录,外联结却有 3 条记录,增加的 1 条记录是 student_id
为 3 的学生 Hao。虽然 score
表并没 student_id
为 3 的成绩,但执行结果仍然把这条记录提取出来了。在实际应用中,如果我们想生成固定行数的数据时,就需要使用外联结。
内联结只会提取同时存在于两张表中的数据,因此 Hao 学生记录并不会出现。对于外联结来说,只要数据存在于某一张表中,就能够提取出来。
同时我们也看到,由于 score
表中并没有 Hao 学生的成绩,所以执行结果该字段为 null。
- 外联结可以指定主表
外联结可以指定哪张表为主表,查询结果会包含主表的所有记录。使用 left
时 from 子句中写在左侧的表是主表,使用 right
时右侧的表是主表。上述外联结代码使用 left
,因此左侧的 student
表是主表。
我们也可以使用 right
对代码进行改写,效果完全一样。
select st.student_id, st.student_name, sc.student_score
from score scright outer join student st on st.student_id = sc.student_id;
至于使用 left
或者 right
,使用哪一个都可以,通常来说,使用 left
的情况多一些。
CROSS JOIN
交叉联结,cross join,是指对联结的表进行笛卡尔积运算。
我们对 student
表和 score
表进行交叉联结:
select st.student_id, st.student_name, sc.student_id, sc.student_score
from student stcross join score sc;
查询结果如下:
student_id | student_name | student_id | student_score |
---|---|---|---|
1 | Leo | 1 | 89 |
2 | Lee | 1 | 89 |
3 | Hao | 1 | 89 |
1 | Leo | 2 | 95 |
2 | Lee | 2 | 95 |
3 | Hao | 2 | 95 |
进行交叉联结时,无法使用内联结和外联结中所使用的 on 子句,这是因为交叉联结是对两张表中的全部记录进行交叉组合,结果记录数是两张表中行数的乘积。student
表包含 3 条记录,score
表包含 2 条记录,故交叉联结结果包含 3 * 2 = 6 条记录。
内联结是交叉联结的一部分,“内”可以理解为“包含在交叉联结结果中的部分”。相反,外联结的“外”可以理解为“交叉联结结果之外的部分”。
在实际应用中,交叉联结使用较少。一是其结果没有实用价值,二是由于结果太多,需要花费大量的运算时间。
过时的语法
上述 sql 代码中,我们使用 inner join
,outer join
等联结关键字符合 sql 标准,但实际开发中,却经常会碰到使用 where
关键字来实现联结。
将上面我们实现内联结的 sql 代码替换成使用 where
来实现:
select st.student_id, st.student_name, sc.student_score
from student st, score sc
where st.student_id = sc.student_id and st.student_id = 1;
执行结果以下:
student_id | student_name | student_score |
---|---|---|
1 | Leo | 89 |
这样的书写方式的查询结果与标准语法的查询结果相同,但这种语法不仅已过时,还存在其他问题:
- 难以判断是内联结还是外联结
- 难以判断哪部分是联结条件,哪部分是用来选取记录的限制条件
- 可能在将来不能使用
虽然不建议使用过时的语法,但我们仍然需要具备阅读这些过时语法代码的能力 ?
参考资料
- SQL 基础教程,第 2 版,MICK 著,孙淼,罗勇译
SQL JOIN 的使用相关推荐
- Mysql: SQL JOIN 子句详解
SQL JOIN 子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段. 最常见的 JOIN 类型:SQL INNER JOIN(简单的 JOIN).SQL LEFT JOIN.SQL ...
- Spark SQL JOIN操作代码示例
title: Spark SQL JOIN操作 date: 2021-05-08 15:53:21 tags: Spark 本文主要介绍 Spark SQL 的多表连接,需要预先准备测试数据.分别创建 ...
- java map join_HashMap 常见应用:实现 SQL JOIN
在我的上一篇文章中,讲到了我自己初步认识 HashMap 的一个经验分享:HashMap 浅析 -- LeetCode Two Sum 刷题总结.作为一个 CRUD 工程师,平时很少接触到基础组件的涉 ...
- SQL JOIN\SQL INNER JOIN 关键字\SQL LEFT JOIN 关键字\SQL RIGHT JOIN 关键字\SQL FULL JOIN 关键字...
SQL join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据. Join 和 Key 有时为了得到完整的结果,我们需要从两个或更多的表中获取结果.我们就需要执行 join. 数据库中的表 ...
- sql(join on 和where的执行顺序)
sql(join on 和where的执行顺序) left join :左连接,返回左表中所有的记录以及右表中连接字段相等的记录. right join :右连接,返回右表中所有的记录以及左表中连接字 ...
- SQL JOIN,你想知道的应该都有
介绍 这是一篇阐述SQL JOINs的文章,本文是国内大佬翻译的一篇文章,为了更容易理解,以MySQL为例在最后面加了示例,原文链接为:https://www.cnblogs.com/xufeiyan ...
- sql join语句语法_SQL Left Join语句:示例语法
sql join语句语法 对于本指南,我们将讨论SQL LEFT JOIN. (For this guide we'll discuss the SQL LEFT JOIN.) Using the k ...
- Spark SQL join的三种实现方式
引言 join是SQL中的常用操作,良好的表结构能够将数据分散到不同的表中,使其符合某种规范(mysql三大范式),可以最大程度的减少数据冗余,更新容错等,而建立表和表之间关系的最佳方式就是join操 ...
- sql join 示例_SQL CROSS JOIN与示例
sql join 示例 In this article, we will learn the SQL CROSS JOIN concept and support our learnings with ...
- SQL JOIN TABLES:在SQL Server中使用查询
In this article, you will see how to use different types of SQL JOIN tables queries to select data f ...
最新文章
- Ubuntu下hadoop的安装与简单应用
- Neo4j CQL - (3) -RETURN子句
- 关于定点机中的比例因子
- Lunar New Year and Cross Counting
- 【项目】itdage-java获取天气和发短信
- lintcode433 岛屿的个数
- 使用delphi开发人工智能程序(环境搭建)
- 软件评测师-专业英语
- STM32 避障小车 —— HC-SR04
- 苹果手机微信语音没声音怎么回事_【云喇叭】微信+支付宝收款语音播报音箱一体机,播报声音大,嘈杂环境也听得见,自带流量卡可连WiFi,无需蓝牙,手机不在店里也播报...
- python tensorflow 以图搜图_以图搜图系统工程实践
- 根据日期获取周数的计算
- 时艳强对话王团长:EOS如果失去社群共识,也就没什么价值了
- 学计算机的第一天,计算机人的一天
- UniAPP Android 蓝牙 ESCPOS打印机 打印图片和二维码
- screentogif能录制声音吗_如何用Screen to Gif快速录制动图
- 如何为你的 Windows 应用程序关联一种或多种文件类型
- 红帽OpenStack私有云部署
- 图像处理—CIF to QCIF记录
- 网络变压器的工作原理:网络变压器中的直流电阻对阻断EMI有怎样的影响?