03--SQLtie三言两语SQLtie链接(join)
本文将从连接的理论和语法讲起,结合具体的例子,详细分析 SQL 连接。
之前对数据库的连接操作似懂非懂,大概知道是什么东西,但是面试笔试的时候被虐成渣,讲不清连接到底是什么。吃一堑,长一智。这就是所谓的似懂非懂, 只是单纯的看书是没用的,只有亲自动手做实验才能彻底理解什么是连接。
连接类型与条件
SQL 中每一种连接操作都包括一个连接类型和连接条件。
连接类型
连接类型决定了如何处理连接条件不匹配的记录。
| 连接类型 | 返回结果 |
|---|---|
| inner join | 只包含左右表中满足连接条件的记录 |
| left outer join | 在内连接的基础上,加入左表中不与右表匹配的记录,剩余字段赋值为null |
| right outer join | 在内连接的基础上,加入右表中不与左表匹配的记录,剩余字段赋值为null |
| full outer join | 左外连接和右外连接的组合。 |
| cross join | 等价于没有连接条件的内连接(即产生笛卡尔乘积) |
关键字 inner 和 outer 是可选的,因为根据连接类型的其余内容我们可以判断出连接是内连接和外连接。简单来说就是:除了单独的 join 是内连接,其他都是外连接。
对外连接来说,连接条件是 必须的 ;但对内连接来说,连接条件是 可选的 (如果省略,将产生笛卡尔积)。
连接条件
连接条件决定两个表中哪些记录互相匹配以及连接结果中出现哪些属性。
| 连接条件 | 修饰位置 | 语义 |
|---|---|---|
| natural | 连接类型之前 | 连接两个表之间的所有公共字段相等的记录,合并相同的列 |
| on <谓词> | 连接类型之后 | 连接符合谓词的记录,不合并相同的列 |
| using(A1, A2,…,An) | 连接类型之后 | natural 语义的子集,只连接两个表中(A1,A2,..An)的公共字段,合并相同的列 |
从上面的描述可以看到:连接操作是连接类型和连接条件的组合,只有在这个前提下才能真正的理解连接的功能。
FQA
例子中使用到的表
student +----+--------+
| id | name |
+----+--------+
| | 张三 |
| | 李四 |
| | 王二 |
| | 初一 |
| | 初二 |
+----+--------+
teacher +----+-----------+
| id | name |
+----+-----------+
| | 王老师 |
| | 李老师 |
| | 张老师 |
| | 肖老师 |
| | NULL |
| | 陈老师 |
+----+-----------+
course +----+--------+------+
| id | cname | tid |
+----+--------+------+
| | 数学 | |
| | 英语 | |
| | 语文 | |
| | 体育 | |
| | 物理 | NULL |
+----+--------+------+
student_course +-----+-----+
| sid | cid |
+-----+-----+
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
+-----+-----+
内连接之后的结果集数量是多少?等于左表或者右表中记录的数量吗?
内连接 teacher course 的结果
select * from teacher inner join course on teacher.id = course.tid;
+----+-----------+----+--------+------+
| id | name | id | cname | tid |
+----+-----------+----+--------+------+
| | 王老师 | | 数学 | |
| | 李老师 | | 英语 | |
| | 张老师 | | 语文 | |
| | 王老师 | | 体育 | |
+----+-----------+----+--------+------+
可以发现,王老师同时教数学和体育,因此左表中王老师匹配了右表中两条记录,物理没有老师教,所以没有出现在结果中。说明 内连接的结果集数量等于左右表中匹配记录的数量 。
左连接之后的结果集数量是多少?等于左表的记录数量吗?
左连接 teacher course 的结果
select * from teacher left join course on teacher.id = course.tid;
+----+-----------+------+--------+------+
| id | name | id | cname | tid |
+----+-----------+------+--------+------+
| | 王老师 | | 数学 | |
| | 李老师 | | 英语 | |
| | 张老师 | | 语文 | |
| | 王老师 | | 体育 | |
| | 肖老师 | NULL | NULL | NULL |
| | NULL | NULL | NULL | NULL |
| | 陈老师 | NULL | NULL | NULL |
+----+-----------+------+--------+------+
可以看到,没有教授课程的老师也出现在结果中,对应的字段都为NULL。说明结果集的数量并不等于左表记录的数量,因为两个表直接不是一对一的关系。其数量应该等于 内连接的结果集数量加上左表中不匹配的记录数量 。
Mysql 中不支持 full outer join
可以通过 union 操作模拟。
SELECT * FROM teacher
LEFT JOIN course ON teacher.id = course.tid
UNION
SELECT * FROM teacher
RIGHT JOIN course ON teacher.id = course.id; +------+-----------+------+--------+------+
| id | name | id | cname | tid |
+------+-----------+------+--------+------+
| | 王老师 | | 数学 | |
| | 李老师 | | 英语 | |
| | 张老师 | | 语文 | |
| | 王老师 | | 体育 | |
| | 肖老师 | NULL | NULL | NULL |
| | NULL | NULL | NULL | NULL |
| | 陈老师 | NULL | NULL | NULL |
| | 肖老师 | | 体育 | |
| | NULL | | 物理 | NULL |
+------+-----------+------+--------+------+
多表连接问题 考虑查出所有学生的课程的记录 select * from student
left join student_course on student.id = student_course.sid
left join course on student_course.cid = course.id; +----+--------+------+------+------+--------+------+
| id | name | sid | cid | id | cname | tid |
+----+--------+------+------+------+--------+------+
| | 张三 | | | | 数学 | |
| | 李四 | | | | 数学 | |
| | 张三 | | | | 英语 | |
| | 张三 | | | | 语文 | |
| | 李四 | | | | 体育 | |
| | 初一 | | | | 体育 | |
| | 王二 | | | | 物理 | NULL |
| | 王二 | | | NULL | NULL | NULL |
| | 初二 | NULL | NULL | NULL | NULL | NULL |
+----+--------+------+------+------+--------+------+
用学生表连接中间表,再连接课程表可以得到结果。连接操作是针对两个表之间的,所以上面的结果是从左到右,两两连接得到的。
如果你有更多关于连接的问题,或者发现文章中的错误,欢迎留言交流
参考资料
《数据库系统概念》
03--SQLtie三言两语SQLtie链接(join)的更多相关文章
- 2018.03.27 python pandas merge join 使用
#2.16 合并 merge-join import numpy as np import pandas as pd df1 = pd.DataFrame({'key1':['k0','k1','k2 ...
- 数据库 的几种链接 join
直接demo,懒的同学可以看看效果 两个表的数据 join和inner join一样 full join报错,可有大神知道原因?
- 十几张表的join(千万级/百万级表) 7hours-->5mins
================START============================== 来了一个mail说是job跑得很慢,调查下原因 先来看下sql: SELECT h.order_ ...
- sort merge join导致temp被爆菊
SQL_ID cqsz37256v36j, child number 1 ------------------------------------- INSERT /*+append*/ INTO T ...
- oracle相关的知识
01.表空间的创建与删除 Spool 目录 (把sql语句都记录在txt文件中)spool e:\xxx.txtSpool off 结束 SQL> --清除屏幕信息SQL> cle ...
- 013:Rank、视图、触发器、MySQL内建函数
一. Rank 给出不同的用户的分数,然后根据分数计算排名 (gcdb@localhost) 09:34:47 [mytest]> create table t_rank(id int,scor ...
- 20170621_oracle练习
========================= 启动Oracle ========================= --->启动OracleOraDb11g_home1TNSListene ...
- .Netcore 2.0 Ocelot Api网关教程(4)- 服务发现
本文介绍Ocelot中的服务发现(Service Discovery),Ocelot允许指定一个服务发现提供器,之后将从中寻找下游服务的host和port来进行请求路由.关于服务发现的详细介绍请点击. ...
- sql monitor生成不了报告& FFS hint不生效两个问题思考
事情的发生就是这么偶然,一步步的深入才能汲取到更深入的知识~~ -------------------START------------------------------------------- ...
随机推荐
- 拷贝构造和拷贝赋值、静态成员(static)、成员指针、操作符重载(day06)
十七 拷贝构造和拷贝赋值 浅拷贝和深拷贝 )如果一个类中包含指针形式的成员变量,缺省的拷贝构造函数只是复制了指针变量的本身,而没有复制指针所指向的内容,这种拷贝方式称为浅拷贝. )浅拷贝将导致不同对象 ...
- 单例模式的理解【php】
单例模式(Singleton Pattern):顾名思义,就是只有一个实例.作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例. 为什么要使用单例模式 1.P ...
- 【hihocoder 1499】A Box of Coins
[题目链接]:http://hihocoder.com/problemset/problem/1499 [题意] [题解] 贪心,模拟; 从左往右对于每一列; 如果上下两个格子; ① 有一个格子超过了 ...
- Java Web学习总结(28)——Java Web项目MVC开源框架SSH和SSM比较
SSH和SSM定义 SSH 通常指的是 Struts2 做控制器(controller),spring 管理各层的组件,hibernate 负责持久化层. SSM 则指的是 SpringMVC 做控制 ...
- Drop a database in MongoDB
http://www.linuxask.com/questions/drop-a-database-in-mongodb Drop a database in MongoDB Answer: Assu ...
- hdu 1384 查分约束
#include<stdio.h> /* 要善于挖掘隐含条件 dis[v]-dis[u]>=bian[i].w;一个条件(u,v,bian[i].w); dis[i+1]>=d ...
- NYOJ 一笔画问题 欧拉路
一笔画问题 时间限制:3000 ms | 内存限制:65535 KB 难度:4 描述 zyc从小就比较喜欢玩一些小游戏,其中就包括画一笔画,他想请你帮他写一个程序,判断一个图是否能够用一笔画下 ...
- kettle 递归循环
var i = new Number(parent_job.getVariable(; parent_job.setVariable("i",i); true;
- linux下Oracle11g RAC搭建(七)
linux下Oracle11g RAC搭建(七) 六.安装Grid 启动GRID安装界面 方式一:redhat下调整分辨率 [root@node1 ~]# xhost + //授权 [ro ...
- elasticsearch插件开发
检索引擎Elasticsearch支持插件模式.有些时候你可能须要安装一些插件.甚至自己开发插件,这里就提供一个開始ES插件开发演示样例,ES版本号为1.5.2. 一.插件类继承自org.elasti ...