在数据库设计中,基本上都是根实体ER关系和范式设计多张表。这样更能设计出更合理、紧凑的表结构,提高有效数据存储,数据的管理维护更简便,也提高了库表的伸缩性。

但是事物总是平衡的,在很多场景中单张表的数据不能满足需求,需要根据多张关联表的数据逻辑关系,返回关联数据。如:查询选修了英语课程的所有学生信息。这里就涉及到学生和课程实体的之间的关联关系。这种查询必然需要操作两张表:

  1. 可以分步骤多次查询
  2. 也可以使用前面提到的子查询

但是这两种方式性能不如:联结。这也是多张表的带来的弊端:SQL的复杂化,DBMS需要更强的功能支持。

join是将多张表混合在一起根据数据之间的逻辑关系进行查询操作。联结的类型很多:

  • 自联结
  • 自然联结(等值联结或者内连接)
  • 外链接

自联结:同一张表使用别名和自己进行连接查询

自然连接:多张表使用逻辑关联列进行进行联结查询,只查询出关联列在多张表完全相等的数据,多张表中对于的未关联上的数据不在查询结果中。

外联结:针对上述自然连接,如果需要将未关联上的行也需要查询,即是外联结。外联结根据查询出不同表的未关联的数据,又分为:左联结、右联结、全联结。

下面看个例子:

前提:

create table student (stu_id int, stu_name varchar(10), stu_age smallint);
create table course(course_id int, course_name varchar(10));
create table score(stu_id int, course_id int, score float); insert into student(stu_id, stu_name, stu_age) values (1, 'xx', 15),(2, 'dd', 17),(3, 'zz', 18);
insert into student(stu_id, stu_name, stu_age) values (4, 'gg', 15); insert into course(course_id, course_name) values (1, 'shuxue'),(2, 'yuwen'),(3, 'yingyu'),(4, 'wuli'),(5, 'huaxue');
insert into score(stu_id, course_id, score) values (1, 1, 87.5),(1, 2, 79.7),(1, 3, 90.3),(1, 4, 89.1),(1, 5, 91.4);
insert into score(stu_id, course_id, score) values (2, 1, 71.4),(2, 2, 56.3),(2, 3, 78.4),(2, 4, 89.1),(2, 5, 93.2);
insert into score(stu_id, course_id, score) values (3, 1, 59.4),(3, 2, 40.3),(3, 3, 25.4),(3, 4, 100),(3, 5, 98.9); insert into score(stu_id, course_id, score) values (4, 1, 16.0),(4, 2, 20.5),(4, 3, 19.4);

-- 查询英语成绩在90分及以上的学生

select stu.* from student as stu, score as sco where stu.stu_id = sco.stu_id and sco.course_id = 3 and sco.score >= 90;

-- 查询每个学生的所有课程的分数

select tmp.stu_name, tmp.score, cos.course_name from (select stu.stu_name, sco.score, sco.course_id from student as stu left outer join score as sco on stu.stu_id = sco.stu_id) as tmp left outer join course as cos on tmp.course_id = cos.course_id order by tmp.stu_name, tmp.score;

自联结和内联结时,条件子句一般使用where,在外联结中多数使用on子句。

内联结:可以直接在from子句后用逗号分割表名,亦可以使用inner join关键字联结表名

左联结:可以使用left join或者left outer join关键字联结表名

右联结:可以使用right join或者rigth outer join关键字联结表名

全连接:可以使用full join或者full outer join关键字联结表名

下面再来看下区别几种外联结的区别:

-- 左联结

select stu.*, sco.course_id, sco.score from student as stu left join score as sco on stu.stu_id = sco.stu_id;

结果:

stu_id stu_name stu_age course_id score
1 xx 15 1 87.5
1 xx 15 2 79.7
1 xx 15 3 90.3
1 xx 15 4 89.1
1 xx 15 5 91.4
2 dd 17 1 71.4
2 dd 17 2 56.3
2 dd 17 3 78.4
2 dd 17 4 89.1
2 dd 17 5 93.2
3 zz 18 1 59.4
3 zz 18 2 40.3
3 zz 18 3 25.4
3 zz 18 4 100
3 zz 18 5 98.9
4 gg 15 1 16
4 gg 15 2 20.5
4 gg 15 3 19.4
5 mm 28 NULL NULL

可以看出最后一行中关于分数的部分全是null,这就是左联结的特点,如果左边表的数据在右边无法连接,则全部补null。

右联结同理,这里就不再赘述。

参考

《SQL必知必会》

SQL系列(十)—— 联结(join)的更多相关文章

  1. 为什么不让用join?《死磕MySQL系列 十六》

    大家好,我是咔咔 不期速成,日拱一卒 在平时开发工作中join的使用频率是非常高的,很多SQL优化博文也让把子查询改为join从而提升性能,但部分公司的DBA又不让用,那么使用join到底有什么问题呢 ...

  2. SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据

    原文:SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Se ...

  3. SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息

    原文:SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2 ...

  4. sql表连接left join,right join,inner join三者之间的区别

    sql表连接left join,right join,inner join区别 left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 (以左表数据为基准,不足补为NULL) ...

  5. SQL学习之联结表的使用

    1.简介:"联结(join)表"是SQL最强大的功能之一.联结是利用SQL的SELECT能执行的最重要的操作,很好地理解联结及其语法是学习SQL的极为重要的部分! 在能够有效的使用 ...

  6. 学习ASP.NET Core Razor 编程系列十八——并发解决方案

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  7. 微软BI 之SSIS 系列 - Merge, Merge Join, Union All 合并组件的使用以及Sort 排序组件同步异步的问题

    开篇介绍 SSIS Data Flow 中有几个组件可以实现不同数据源的数据合并功能,比如 Merger, Merge Join 和 Union All.它们的功能比较类似,同时也比较容易混淆,下面是 ...

  8. MP实战系列(十四)之分页使用

    MyBatis Plus的分页,有插件式的,也有其自带了,插件需要配置,说麻烦也不是特别麻烦,不过觉得现有的MyBatis Plus足以解决,就懒得配置插件了. MyBatis Plus的资料不算是太 ...

  9. sql语句中left join、right join 以及inner join之间的使用与区别

    sql语句中left join.right join 以及innerjoin之间的使用与区别 left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录  right join( ...

  10. MySql必知必会实战练习(四)主键、外键、sql约束、联结表

    本博将对主键.外键.MySql数据库约束和联结表的相关特性进行总结和实战 1. 主键 表中的每一行都应该具有可以唯一标识自己的一列(或一组列),而这个承担标识作用的列称为主键 如果没有主键,数据的管理 ...

随机推荐

  1. OAuth 2.0 的四种授权模式

    RFC 6749 OAuth 2.0 的标准是 RFC 6749 文件.该文件先解释了 OAuth 是什么. OAuth 引入了一个授权层,用来分离两种不同的角色:客户端和资源所有者.......资源 ...

  2. Linux命令查找文件目录

    座右铭:长风破浪会有时,直挂云帆济沧海. linux一般查看文件或者目录有几种方法. /查看文件类容--------cat/more/less/head/tail   只能查看文本型(txt) (1) ...

  3. 10年前错过比特币,如今有斯坦福区块链项目pi币,对标btc,手机免费挖矿详细教程。

    这一个斯坦福几个博士创业者做一个项目,目前还处于早期阶段,除了每天点一下挖矿之外,貌似不需要其他的操作,不需要耗费流量资源和手机大量的运算能力,就是一个安静的App而已....国内目前知道的人还不太多 ...

  4. sftp常用命令

    help 查看sftp支持哪些命令 ls  查看当前目录下文件 cd 指定目录 lcd 更改和/或打印本地工作目录 pwd 查看当前目录 lpwd 打印本地工作目录 get xxx.txt 下载xxx ...

  5. 前端性能优化 http请求的过程及潜在的优化点

    CS架构:比如我们的代码开发好,打包成apk,发布到平台,那么最终怎么运行到用户的手机上呢,用户首先需要从相关的应用商城下载这个apk包,并且运行这个 apk 包,那么这个 apk 包就会被解压,最后 ...

  6. linux命令:set 指定行,直接替换并修改文件

    sed 命令: 指定行,从第一行到第一行: 把该行的ssd,换成cd: -i 表示的是替换并直接修改文件: sed  -i  '1,1s/ssd/cd/g' test_file 命令使用: sed - ...

  7. 【Linux】文件拷贝-Linux当前目录所有文件移动到上一级目录(转)

    Linux当前目录所有文件移动到上一级目录 mv * ../

  8. robot framework Selenium2library wait小问题

    最近在使用selenium2Library时,用到其中的 Wait Until Page函数,因我们的网页相对比较敏感,经常获取不到,不明觉历 看看源码吧,如下: def wait_until_pag ...

  9. 【转】编写高质量代码改善C#程序的157个建议——建议56:使用继承ISerializable接口更灵活地控制序列化过程

    建议56:使用继承ISerializable接口更灵活地控制序列化过程 接口ISerializable的意义在于,如果特性Serializable,以及与其像配套的OnDeserializedAttr ...

  10. winform解决方案资源管理器