数据库表的各种连接(内连接,外连接)

来源:互联网 发布:vb开发的软件有哪些 编辑:程序博客网 时间:2024/06/05 20:30
关系型数据库,以关系代数为理论基础:
1、用表(Table)表示关系或者实体;
2、用行(Row)表示元组。
3、用列(Col)表示属性。
关系代数包含以下8个关系运算符:
单表操作:
1、选取――返回满足指定条件的行。
2、投影――从数据集合中返回指定的列。
相同结构的两表操作:
3、并――关系的加法和减法,它可以在行的方向上合并两个表中的数据。
4、交――返回两个数据集合所共有的行。
5、差――返回只属于一个数据集合的行。
不同结构的两表操作:
6、笛卡尔积――是关系的乘法,它将分别来自两个数据集合中的行以所有可能的方式进行组合。
7、连接――在水平方向上合并两个表,其方法是:将两个表中在共同数据项上相互匹配的那些行合并起来。
8、除――返回两个数据集之间的精确匹配。
在关系代数中,连接运算是由一个笛卡尔积运算和一个选取运算构成的。
首先用笛卡尔积完成对两个数据集合的乘运算,然后对生成的结果集合进行选取运算,
确保只把分别来自两个数据集合并且具有重叠部分的行合并在一起。
连接的全部意义在于在水平方向上合并两个数据集合(通常是表),并产生一个新的结果集合,
其方法是将一个数据源中的行于另一个数据源中和它匹配的行组合成一个新元组。
SQL提供了多种类型的连接方式,它们之间的区别在于:
从相互交叠的不同数据集合中选择用于连接的行时所采用的方法不同。
连接类型          定义
内连接              只连接匹配的行,又叫等值连接,又生出自然连接。
左外连接          包含左边表的全部行,以及右边表中全部匹配的行。
右外连接          包含右边表的全部行,以及左边表中全部匹配的行。
全外连接          包含左、右两个表的全部行,不管另外一边的表中是否存在与它们匹配的行。
交叉连接          笛卡尔积-它不使用任何匹配或者选取条件,而是直接对两张表的每个行进行交叉匹配。
(H)(theta)连接          使用等值以外的条件来匹配左、右两个表中的行。
连接条件指定各列之间(每个表至少一列)进行连接的关系。
因为正在比较连接条件中的列,所以它们必须具有一致的数据类型。
SELECT语句的FROM子句可以指定以下几种类型的连接:
FROM子句关键字          相应的结果集
CROSS JOIN         笛卡尔积(所有可能的行对);
INNER JOIN          仅对满足连接条件的CROSS中的列;
LEFT OUTER JOIN        一个表满足条件的行,和另一个表的所有行;
RIGHT OUTER JOIN      与LEFT相同,但两个表的角色互换;
FULL OUTER JOIN        LEFT OUTER 和 RIGHT OUTER中所有行的超集。

下面以MySql为例子,给出上述各种连接的演示:

-- ------------------------------ 创建表(`student`)-- ----------------------------DROP TABLE IF EXISTS `student`;CREATE TABLE `student` (  `id` int(10) NOT NULL AUTO_INCREMENT,  `name` varchar(30) CHARACTER SET utf8 NOT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;-- ------------------------------ 往表(student)中添加3条记录-- ----------------------------INSERT INTO `student` VALUES ('1', '张三');INSERT INTO `student` VALUES ('2', '李四');INSERT INTO `student` VALUES ('3', '王五');-- ------------------------------ 创建表(`score`)-- ----------------------------DROP TABLE IF EXISTS `score`;CREATE TABLE `score` (  `id` int(10) NOT NULL,  `score` int(10) NOT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;-- ------------------------------ 往表(score)中添加3条记录-- ----------------------------INSERT INTO `score` VALUES ('1', '60');INSERT INTO `score` VALUES ('2', '75');INSERT INTO `score` VALUES ('4', '90');-- ------------------------------ 表(student)内容如下-- ----------------------------SELECT * FROM student;+----+--------+| id | name   |+----+--------+|  1 | 张三   ||  2 | 李四   ||  3 | 王五   |+----+--------+-- ------------------------------ 表(score)内容如下-- ----------------------------SELECT * FROM score;+----+-------+| id | score |+----+-------+|  1 |    60 ||  2 |    75 ||  4 |    90 |+----+-------+-- ------------------------------ CROSS JOIN,交叉连接,即笛卡尔积,无ON子句;将所有行交叉匹配-- ----------------------------SELECT * FROM student CROSS JOIN score;+----+--------+----+-------+| id | name   | id | score |+----+--------+----+-------+|  1 | 张三   |  1 |    60 ||  2 | 李四   |  1 |    60 ||  3 | 王五   |  1 |    60 ||  1 | 张三   |  2 |    75 ||  2 | 李四   |  2 |    75 ||  3 | 王五   |  2 |    75 ||  1 | 张三   |  4 |    90 ||  2 | 李四   |  4 |    90 ||  3 | 王五   |  4 |    90 |+----+--------+----+-------+-- ------------------------------ NATURAL JOIN,自然连接,无ON子句;选取值相同的行,并把相同列合并成一列-- ----------------------------SELECT * FROM student NATURAL JOIN score;+----+--------+-------+| id | name   | score |+----+--------+-------+|  1 | 张三   |    60 ||  2 | 李四   |    75 |+----+--------+-------+-- ------------------------------ INNER JOIN,等值连接,有ON子句;选取两表中,值相同的行-- ----------------------------SELECT * FROM student INNER JOIN score ON student.id = score.id;+----+--------+----+-------+| id | name   | id | score |+----+--------+----+-------+|  1 | 张三   |  1 |    60 ||  2 | 李四   |  2 |    75 |+----+--------+----+-------+-- ------------------------------ LEFT OUTER JOIN,左外连接,有ON子句;选取值相同的行,和左表不匹配的行-- ----------------------------SELECT * FROM student LEFT OUTER JOIN score ON student.id = score.id;+----+--------+------+-------+| id | name   | id   | score |+----+--------+------+-------+|  1 | 张三   |    1 |    60 ||  2 | 李四   |    2 |    75 ||  3 | 王五   | NULL |  NULL |+----+--------+------+-------+-- ------------------------------ RIGHT OUTER JOIN,右外连接,有ON子句;选取值相同的行,和右表不匹配的行-- ----------------------------SELECT * FROM student RIGHT OUTER JOIN score ON student.id = score.id;+------+--------+----+-------+| id   | name   | id | score |+------+--------+----+-------+|    1 | 张三   |  1 |    60 ||    2 | 李四   |  2 |    75 || NULL | NULL   |  4 |    90 |+------+--------+----+-------+-- ------------------------------ FULL OUTER JOIN,全外连接,MySQL不支持;选取值相同的行,和两表不匹配的行-- ------------------------------SELECT * FROM student FULL OUTER JOIN score ON student.id = score.id;+------+--------+------+-------+| id   | name   | id   | score |+------+--------+------+-------+|    1 | 张三   |  1   |    60 ||    2 | 李四   |  2   |    75 ||    3 | 王五   | NULL |  NULL || NULL | NULL   |  4   |    90 |+------+--------+------+-------+


2 0
原创粉丝点击