内连接和外连接

内连接

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

显式的内连接实例:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值