当前位置: 首页 > news >正文

内连接和外连接

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

内连接

内连接分为: 相等连接,自然连接,和交叉连接

显式的内连接实例:

SELECT * FROM employee INNER JOIN department ON employee.DepartmentID = department.DepartmentID

等价于:

SELECT * FROM employee,department WHERE employee.DepartmentID = department.DepartmentID

相等链接

SELECT * FROM employee INNER JOIN department ON employee.DepartmentID = department.DepartmentID
SELECT * FROM employee INNER JOIN department USING (DepartmentID)
自然连接

两表做自然连接时,两表中的所有名称相同的列都将被比较,这是隐式的。自然连接得到的结果表中,两表中名称相同的列只出现一次.

SELECT * FROM employee NATURAL JOIN department
在  Oracle  里用  JOIN USING  或  NATURAL JOIN  时,如果两表共有的列的名称前加上某表名作为前缀,则会报编译错误: "ORA-25154: column part of USING clause cannot have qualifier" 或 "ORA-25155: column used in NATURAL join cannot have qualifier".

交叉连接

交叉连接(cross join),又称笛卡尔连接(cartesian join)或叉乘(Product),它是所有类型的内连接的基础。把表视为行记录的集合,交叉连接即返回这两个集合的笛卡尔积。这其实等价于内连接的链接条件为"永真",或连接条件不存在.

显式的交叉连接实例:

SELECT * FROM employee CROSS JOIN department

隐式的交叉连接实例:

SELECT * FROM employee ,department;



外连接

外连接并不要求连接的两表的每一条记录在对方表中都一条匹配的记录. 连接表保留所有记录 -- 甚至这条记录没有匹配的记录也要保留. 外连接可依据连接表保留左表, 右表或全部表的行而进一步分为左外连接, 右外连接和全连接.

左外连接

左外连接 会返回左表的所有记录和右表中匹配记录的组合(如果右表中无匹配记录, 来自于右表的所有列的值设为 NULL).

如果左表的一行在右表中存在多个匹配行, 那么左表的行会复制和右表匹配行一样的数量, 并进行组合生成连接结果.

SELECT * FROM employee LEFT OUTER JOIN department ON employee.DepartmentID = department.DepartmentID

        这允许我们去找到雇员的部门时, 显示所有雇员, 即使这个雇员还没有关联的部门.(在上面的内连接部分由一个相反的例子, 没有关联的部门号的雇员在结果中是不显示的).


右外连接

右连接操作返回右表的所有行和这些行在左表中匹配的行(没有匹配的, 来源于左表的列值设为 NULL).

SELECT * FROM employee RIGHT OUTER JOIN department ON employee.DepartmentID = department.DepartmentID
这允许我们在找每一个雇员以及他的部门信息时, 当这个部门里没有任何雇员时, 也把部分显示出来.

实际上显式的右连接很少使用, 因为它总是可以被替换成左连接--换换表的位置就可以了。


全连接

全连接是左右外连接的并集. 连接表包含被连接的表的所有记录, 如果缺少匹配的记录, 即以 NULL 填充.

SELECT * FROM employee FULL OUTER JOIN department ON employee.DepartmentID = department.DepartmentID
这允许我们查看每一个在部门里的员工和每一个拥有雇员的部门, 同时, 还能看到不在任何部门的员工以及没有任何员工的部门.

一些数据库系统(如 MySQL)并不直接支持全连接, 但它们可以通过左右外连接的并集(参: union)来模拟实现. 和上面等价的实例:

SELECT * FROM employee LEFT JOIN department ON employee.DepartmentID = department.DepartmentID UNION SELECT * FROM employee RIGHT JOIN department ON employee.DepartmentID = department.DepartmentID WHERE employee.DepartmentID IS NULL
SELECT * FROM employee LEFT JOIN department ON employee.DepartmentID = department.DepartmentID UNION SELECT * FROM employee RIGHT JOIN department ON employee.DepartmentID = department.DepartmentID WHERE employee.DepartmentID IS NULL

SQLite 不支持右连接, 全外连接可以按照下面的方式模拟:

SELECT employee.*, department.* FROM employee LEFT JOIN department ON employee.DepartmentID = department.DepartmentID UNION SELECT employee.*, department.* FROM department LEFT JOIN employee ON employee.DepartmentID = department.DepartmentID WHERE employee.DepartmentID IS NULL

自连接

自连接就是和自身连接

试图找到这样的记录: 每条记录包含两个雇员, 他们来自于同一个国家. 

SELECT F.EmployeeID, F.LastName, S.EmployeeID, S.LastName, F.Country FROM Employee F, Employee S WHERE F.Country = S.Country AND F.EmployeeID < S.EmployeeID ORDER BY F.EmployeeID, S.EmployeeID;
  • F 和 S 是雇员表(employee)的第一个和第二个拷贝的别名
  • 条件 F.Country = S.Country 排除了在不同国家的雇员的组合. 这个例子仅仅期望得到在相同国家的雇员的组合.
  • 条件 F.EmployeeID < S.EmployeeID 排除了雇员号(EmployeeID)相同的组合.
  • F.EmployeeID < S.EmployeeID 排除了重复的组合. 没有这个条件的话, 将生成类似下面表中的无用数据(仅以 United Kingdom 为例)

替代方式

外连接查询得到的结果也可以通过关联子查询得到. 例如

SELECT employee.LastName, employee.DepartmentID, department.DepartmentName FROM employee LEFT OUTER JOIN department ON employee.DepartmentID = department.DepartmentID

也可以写成如下样子:

SELECT employee.LastName, employee.DepartmentID, (SELECT department.DepartmentName FROM department WHERE employee.DepartmentID = department.DepartmentID ) FROM employee


连接算法

执行一个连接操作, 存在三种基本的算法.嵌套循环、合并连接、哈希连接

原文链接:http://zh.wikipedia.org/wiki/%E8%BF%9E%E6%8E%A5_(SQL)#.E8.87.AA.E7.84.B6.E8.BF.9E.E6.8E.A5

转载于:https://my.oschina.net/u/1186186/blog/178483

相关文章:

  • 阿里丁烨看过程改进:如何提高被改进团队积极性
  • MySQL 性能监控4大指标——第一部分
  • 运行yum报错:No module named yum
  • 如何在Word中插入几何画板图形
  • jQuery().end()的内部实现及源码分析
  • 应用生命周期终极 DevOps 工具包
  • ASP.NET项目与IE10、IE11不兼容的解决办法
  • Selenium webdriver 操作日历控件
  • Qt一步一步实现插件调用(附源码)
  • 如何提高Linux下块设备IO的整体性能?
  • 演示:取证分析IPV6组播地址与MAC地址的映射关系
  • 类的运用(一)
  • ODI中通过配置表和自定义逆向工程获取数据库信息
  • vim的Tab键
  • js prototype之诡异
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • 【跃迁之路】【477天】刻意练习系列236(2018.05.28)
  • create-react-app项目添加less配置
  • Github访问慢解决办法
  • Java 多线程编程之:notify 和 wait 用法
  • npx命令介绍
  • opencv python Meanshift 和 Camshift
  • React组件设计模式(一)
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • 工作踩坑系列——https访问遇到“已阻止载入混合活动内容”
  • 类orAPI - 收藏集 - 掘金
  • 聊聊springcloud的EurekaClientAutoConfiguration
  • 使用common-codec进行md5加密
  • 我有几个粽子,和一个故事
  • 项目实战-Api的解决方案
  • 7行Python代码的人脸识别
  • ​七周四次课(5月9日)iptables filter表案例、iptables nat表应用
  • #{} 和 ${}区别
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • $.ajax()参数及用法
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (python)数据结构---字典
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (免费领源码)python#django#mysql校园校园宿舍管理系统84831-计算机毕业设计项目选题推荐
  • (一)Spring Cloud 直击微服务作用、架构应用、hystrix降级
  • (转)memcache、redis缓存
  • .chm格式文件如何阅读
  • .net CHARTING图表控件下载地址
  • .Net Core缓存组件(MemoryCache)源码解析
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .考试倒计时43天!来提分啦!
  • /ThinkPHP/Library/Think/Storage/Driver/File.class.php  LINE: 48
  • @Bean有哪些属性
  • @media screen 针对不同移动设备
  • @zabbix数据库历史与趋势数据占用优化(mysql存储查询)
  • [ C++ ] STL_list 使用及其模拟实现
  • [ element-ui:table ] 设置table中某些行数据禁止被选中,通过selectable 定义方法解决
  • [ vulhub漏洞复现篇 ] GhostScript 沙箱绕过(任意命令执行)漏洞CVE-2019-6116