SQL系列(十)—— 联结(join)
在数据库设计中,基本上都是根实体ER关系和范式设计多张表。这样更能设计出更合理、紧凑的表结构,提高有效数据存储,数据的管理维护更简便,也提高了库表的伸缩性。
但是事物总是平衡的,在很多场景中单张表的数据不能满足需求,需要根据多张关联表的数据逻辑关系,返回关联数据。如:查询选修了英语课程的所有学生信息。这里就涉及到学生和课程实体的之间的关联关系。这种查询必然需要操作两张表:
- 可以分步骤多次查询
- 也可以使用前面提到的子查询
但是这两种方式性能不如:联结。这也是多张表的带来的弊端: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)的更多相关文章
- 为什么不让用join?《死磕MySQL系列 十六》
大家好,我是咔咔 不期速成,日拱一卒 在平时开发工作中join的使用频率是非常高的,很多SQL优化博文也让把子查询改为join从而提升性能,但部分公司的DBA又不让用,那么使用join到底有什么问题呢 ...
- SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据
原文:SQL Server 2008空间数据应用系列十二:Bing Maps中呈现GeoRSS订阅的空间数据 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Se ...
- SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息
原文:SQL Server 2008空间数据应用系列十:使用存储过程生成GeoRSS聚合空间信息 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Server 2 ...
- sql表连接left join,right join,inner join三者之间的区别
sql表连接left join,right join,inner join区别 left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 (以左表数据为基准,不足补为NULL) ...
- SQL学习之联结表的使用
1.简介:"联结(join)表"是SQL最强大的功能之一.联结是利用SQL的SELECT能执行的最重要的操作,很好地理解联结及其语法是学习SQL的极为重要的部分! 在能够有效的使用 ...
- 学习ASP.NET Core Razor 编程系列十八——并发解决方案
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 微软BI 之SSIS 系列 - Merge, Merge Join, Union All 合并组件的使用以及Sort 排序组件同步异步的问题
开篇介绍 SSIS Data Flow 中有几个组件可以实现不同数据源的数据合并功能,比如 Merger, Merge Join 和 Union All.它们的功能比较类似,同时也比较容易混淆,下面是 ...
- MP实战系列(十四)之分页使用
MyBatis Plus的分页,有插件式的,也有其自带了,插件需要配置,说麻烦也不是特别麻烦,不过觉得现有的MyBatis Plus足以解决,就懒得配置插件了. MyBatis Plus的资料不算是太 ...
- sql语句中left join、right join 以及inner join之间的使用与区别
sql语句中left join.right join 以及innerjoin之间的使用与区别 left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join( ...
- MySql必知必会实战练习(四)主键、外键、sql约束、联结表
本博将对主键.外键.MySql数据库约束和联结表的相关特性进行总结和实战 1. 主键 表中的每一行都应该具有可以唯一标识自己的一列(或一组列),而这个承担标识作用的列称为主键 如果没有主键,数据的管理 ...
随机推荐
- rac启动维护笔记
Ohasd.bin将产生4个代理启动相关的资源 (1) oraagent:负责ora.asm.ora.evmd.ora.gipcd.ora.gpnpd.ora.mdnsd的启动和管理 (2) ...
- HBase安装指南
一.事前准备 此安装是建立在hadoop集群运行起来的基础上,此hadoop版本为2.6.0,其他版本未测试,可能存在兼容性问题. 上传所需文件到/usr/local/soft 二.zookeep ...
- 配置以https访问网站
环境 centos7 nginx1.16.1 一.申请证书(已有域名) 进入阿里云控制台,点击域名(我已经弄好了,一开始是没有ssl选项) 点击免费开启ssl 点购买->选择免费版 购买成功后 ...
- 三、python对字符串和集合的内存垃圾回收机制
变量声明: name1 = "andy" name2 = name1 这个时候我把name1的值给改成了“tom”,问现在name2的值是什么?为什么? 答:andy,因为你把 ...
- 代数&数论趣题集萃
暑假总不能只学习平面几何.所以这里也收集一些有趣的代数题或数论题,同时记下解法的一些提示.给未来的自己复习参考用. 多图片预警(请注意流量) 目录: Part 0:其他(8) Part 1:不等式(1 ...
- ROS官网新手级教程总结
第 1 关卡:安装和配置 ROS 环境 目标:在计算机上安装和配置 ROS 环境. 安装 ROS 按照 ROS 安装说明进行安装. 管理环境 确定环境变量 ROS_ROOT 和 ROS_PACKAGE ...
- php状态模式(state pattern)
... <?php /* The state pattern encapsulates the varying behavior for the same object based on its ...
- Tomcat8 访问 manager App 失败
Tomcat8 访问 manager App 失败 进入 tomcat 8 的下面路径 修改 上面 的 context.xml 注释了下面的框框 保存退出.重启tomcat
- Java 基本类型、封装类型、常量池、基本运算
基本数据类型: byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0 short:短整型,在内存中占16位,即2个字节,取值范围-32768~3 ...
- Angle Beats Gym - 102361A(计算几何)
Angle Beats \[ Time Limit: 4000 ms \quad Memory Limit: 1048576 kB \] 题意 给出 \(n\) 个初始点以及 \(q\) 次询问,每次 ...