在数据库设计中,基本上都是根实体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. 浓缩版java8新特性

    目录 一.Lambda 1.定义/设计原因 2.结构 3.规则 4.使用 二.函数式接口 1.定义 2.设计原因 3.使用 三.方法引用 1.定义/设计原因 2.使用 四.接口的默认方法 1.定义 2 ...

  2. Mysql 主从报错:1141

    主从同步,从库报错代码:1141 ,错误信息如下: Master_Port: 3306 Connect_Retry: 60 Master_Log_File: binlog.000086 Read_Ma ...

  3. svn更换repos时保留svn log

    两种情况 1. 直接移动库 问题:svn如何把A服务器上的reposA上传到B服务器的reposB并保留各种上传更新记录? 这个问题要感想敢干,直接复制改名即可 #登录到B服务器 scp -r cmo ...

  4. Linux shell awk模式使用

    awk的PATTERN表示方法: 1,正则表达式,格式为/regex/ 以冒号为分隔符,显示/etc/passwd以r开头的行的第一段 [root@wei awk]# awk -F: '/^r/{pr ...

  5. BareTail(日志查看工具)

    官网:http://www.baremetalsoft.com/baretail/index.php 在看log文件时,当日志有新增时,会自动滚动到最新的那一行,对于查看实时日志有作用.

  6. JAVA类与类之间的关系及代码示例

    参考链接:https://blog.csdn.net/wq6ylg08/article/details/81092056

  7. docker删除镜像Error response from daemon: conflict: unable to remove repository reference

    Docker无法删除images,由于是依赖container. 1.进入root权限   sudo su 2. 列出所有运行或没有运行的镜像  docker  ps  -a 3.停止containe ...

  8. excel的IRR函数

    office官网找到IRR的介绍 https://support.office.com/zh-cn/article/irr-%E5%87%BD%E6%95%B0-64925eaa-9988-495b- ...

  9. Echarts在同一网页按顺序展示多图

    Echarts Page:同一网页按顺序展示多图 from pyecharts import Page page = Page("") page.add(pie).add(frie ...

  10. Pandas | 19 合并/连接

    Pandas具有功能全面的高性能内存中连接操作,与SQL等关系数据库非常相似.Pandas提供了一个单独的merge()函数,作为DataFrame对象之间所有标准数据库连接操作的入口 - pd.me ...