由于工作需要,现在也开始写一些复杂一点的 sql 了。由于之前对于 joinwhere 关键字的使用一直有疑惑,故写一篇文章整理一下,算是对 sql 中各种表联结使用的一个总结。

SQL JOIN 的作用

sql 关键字 unionintersect 属于以行方向为单位的集合运算,进行这些集合运算时,会导致记录行数的增加或减少。
关键字 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 joinstudent 表和 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 joinouter 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 的使用相关推荐

  1. Mysql: SQL JOIN 子句详解

    SQL JOIN 子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段. 最常见的 JOIN 类型:SQL INNER JOIN(简单的 JOIN).SQL LEFT JOIN.SQL  ...

  2. Spark SQL JOIN操作代码示例

    title: Spark SQL JOIN操作 date: 2021-05-08 15:53:21 tags: Spark 本文主要介绍 Spark SQL 的多表连接,需要预先准备测试数据.分别创建 ...

  3. java map join_HashMap 常见应用:实现 SQL JOIN

    在我的上一篇文章中,讲到了我自己初步认识 HashMap 的一个经验分享:HashMap 浅析 -- LeetCode Two Sum 刷题总结.作为一个 CRUD 工程师,平时很少接触到基础组件的涉 ...

  4. SQL JOIN\SQL INNER JOIN 关键字\SQL LEFT JOIN 关键字\SQL RIGHT JOIN 关键字\SQL FULL JOIN 关键字...

    SQL join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据. Join 和 Key 有时为了得到完整的结果,我们需要从两个或更多的表中获取结果.我们就需要执行 join. 数据库中的表 ...

  5. sql(join on 和where的执行顺序)

    sql(join on 和where的执行顺序) left join :左连接,返回左表中所有的记录以及右表中连接字段相等的记录. right join :右连接,返回右表中所有的记录以及左表中连接字 ...

  6. SQL JOIN,你想知道的应该都有

    介绍 这是一篇阐述SQL JOINs的文章,本文是国内大佬翻译的一篇文章,为了更容易理解,以MySQL为例在最后面加了示例,原文链接为:https://www.cnblogs.com/xufeiyan ...

  7. sql join语句语法_SQL Left Join语句:示例语法

    sql join语句语法 对于本指南,我们将讨论SQL LEFT JOIN. (For this guide we'll discuss the SQL LEFT JOIN.) Using the k ...

  8. Spark SQL join的三种实现方式

    引言 join是SQL中的常用操作,良好的表结构能够将数据分散到不同的表中,使其符合某种规范(mysql三大范式),可以最大程度的减少数据冗余,更新容错等,而建立表和表之间关系的最佳方式就是join操 ...

  9. sql join 示例_SQL CROSS JOIN与示例

    sql join 示例 In this article, we will learn the SQL CROSS JOIN concept and support our learnings with ...

  10. 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 ...

最新文章

  1. Ubuntu下hadoop的安装与简单应用
  2. Neo4j CQL - (3) -RETURN子句
  3. 关于定点机中的比例因子
  4. Lunar New Year and Cross Counting
  5. 【项目】itdage-java获取天气和发短信
  6. lintcode433 岛屿的个数
  7. 使用delphi开发人工智能程序(环境搭建)
  8. 软件评测师-专业英语
  9. STM32 避障小车 —— HC-SR04
  10. 苹果手机微信语音没声音怎么回事_【云喇叭】微信+支付宝收款语音播报音箱一体机,播报声音大,嘈杂环境也听得见,自带流量卡可连WiFi,无需蓝牙,手机不在店里也播报...
  11. python tensorflow 以图搜图_以图搜图系统工程实践
  12. 根据日期获取周数的计算
  13. 时艳强对话王团长:EOS如果失去社群共识,也就没什么价值了
  14. 学计算机的第一天,计算机人的一天
  15. UniAPP Android 蓝牙 ESCPOS打印机 打印图片和二维码
  16. screentogif能录制声音吗_如何用Screen to Gif快速录制动图
  17. 如何为你的 Windows 应用程序关联一种或多种文件类型
  18. 红帽OpenStack私有云部署
  19. 图像处理—CIF to QCIF记录
  20. 网络变压器的工作原理:网络变压器中的直流电阻对阻断EMI有怎样的影响?

热门文章

  1. Android studio 实现计算器android 开发小实验
  2. 丰趣海淘:跨境电商平台的前端性能优化实践
  3. 手机计算机数字显示在桌面上,手机桌面上的应用如何取消显示的数字角标
  4. 计算机准考证全是乱码怎么回事----准考证打印问题
  5. 滴滴插件化方案 VirtualApk 源码解析
  6. 搭建网站?(手把手教你)
  7. 情景剧《寝室那点事》
  8. 【面经】2022社招软件测试面试(3)-腾讯CSIG云网络测试开发
  9. ZStack Cloud助力深圳燃气打造智慧燃气,纳管阿里云和VMware
  10. C语言中的几种排序算法