关于 JOIN 耐心总结,学不会你打我系列

现在随着各种数据库框架的盛行,在提高效率的同时也让我们忽略了很多底层的连接过程,这篇文章是对 SQL 连接过程梳理,并涉及到了现在常用的 SQL 标准。

其实标准就是在不同的时间,制定的一些写法或规范。

从 SQL 标准说起

在编写 SQL 语句前,需要先了解在不同版本的规范,因为随着版本的变化,在具体编写 SQL 时会有所不同。对于 SQL 来说,SQL92 和 SQL99 是最常见的两个 SQL 标准,92 和 99 对应其提出的年份。除此之外,还存在 SQL86、SQL89、SQL2003、SQL2008、SQL2011,SQL2016等等。

但对我们来说,SQL92 和 SQL99 是最常用的两个标准,主要学习这两个就可以了。

为了演示方便,现在数据库中加入如下三张表:

每个学生属于一个班级,通过班级的人数来对应班级的类型。

-- ----------------------------
DROP TABLE IF EXISTS `Student`;
CREATE TABLE `Student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '',
  `birth` varchar(20) NOT NULL DEFAULT '',
  `sex` varchar(10) NOT NULL DEFAULT '',
  `class_id` int(11) NOT NULL COMMENT '班级ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of Student
-- ----------------------------
INSERT INTO `Student` VALUES ('1', '胡一', '1994.1.1', '男', '1');
INSERT INTO `Student` VALUES ('3', '王阿', '1992.1.1', '女', '1');
INSERT INTO `Student` VALUES ('5', '王琦', '1993.1.2', '男', '1');
INSERT INTO `Student` VALUES ('7', '刘伟', '1998.2.2', '女', '1');
INSERT INTO `Student` VALUES ('11', '张使', '1994.1.1', '男', '3');
INSERT INTO `Student` VALUES ('13', '王阿', '1992.1.1', '女', '3');
INSERT INTO `Student` VALUES ('15', '夏琪', '1993.1.2', '男', '3');
INSERT INTO `Student` VALUES ('17', '刘表', '1998.2.2', '女', '3');
INSERT INTO `Student` VALUES ('19', '诸葛', '1994.1.1', '男', '3');
INSERT INTO `Student` VALUES ('21', '王前', '1992.1.1', '女', '3');
INSERT INTO `Student` VALUES ('23', '王意识', '1993.1.2', '男', '3');
INSERT INTO `Student` VALUES ('25', '刘等待', '1998.2.2', '女', '3');
INSERT INTO `Student` VALUES ('27', '胡是一', '1994.1.1', '男', '5');
INSERT INTO `Student` VALUES ('29', '王阿请', '1992.1.1', '女', '5');
INSERT INTO `Student` VALUES ('31', '王消息', '1993.1.2', '男', '5');
INSERT INTO `Student` VALUES ('33', '刘全', '1998.2.2', '女', '5');
INSERT INTO `Student` VALUES ('35', '胡爱', '1994.1.1', '男', '5');
INSERT INTO `Student` VALUES ('37', '王表', '1992.1.1', '女', '5');
INSERT INTO `Student` VALUES ('39', '王华', '1993.1.2', '男', '5');
INSERT INTO `Student` VALUES ('41', '刘伟以', '1998.2.2', '女', '5');
INSERT INTO `Student` VALUES ('43', '胡一彪', '1994.1.1', '男', '5');
INSERT INTO `Student` VALUES ('45', '王阿符', '1992.1.1', '女', '5');
INSERT INTO `Student` VALUES ('47', '王琦删', '1993.1.2', '男', '5');
INSERT INTO `Student` VALUES ('49', '刘达达', '1998.2.2', '女', '5');

-- ----------------------------
-- Table structure for `Class`
-- ----------------------------
DROP TABLE IF EXISTS `Class`;
CREATE TABLE `Class` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '',
  `number` int(11) NOT NULL DEFAULT 0,
  `class_type_id` int(11) NOT NULL COMMENT '班级类型ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of Class
-- ----------------------------
INSERT INTO `Class` VALUES ('1', '1年1班', 4, '1');
INSERT INTO `Class` VALUES ('3', '1年2班', 8, '3');
INSERT INTO `Class` VALUES ('5', '1年3班', 12, '5');

DROP TABLE IF EXISTS `ClassType`;
CREATE TABLE `ClassType`(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(20) NOT NULL DEFAULT '',
  `minimum_number` int(11) NOT NULL DEFAULT 0 COMMENT '最少的班级人数',
  `maximum_number` int(11) NOT NULL DEFAULT 0 COMMENT '最多的班级人数',
  PRIMARY KEY(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `ClassType` VALUES ('1', '小班', '1', '4');
INSERT INTO `ClassType` VALUES ('3', '中班', '5', '8');
INSERT INTO `ClassType` VALUES ('5', '大班', '9', '12');

SQL92

笛卡尔积(交叉连接)

笛卡尔积是一个数学上的概念,表示如果存在 X,Y 两个集合,则 X,Y 的笛卡尔积记为 X * Y. 表示由 X,Y 组成有序对的所有情况。

对应在 SQL 中,就是将两张表中的每一行进行组合。而且在连接时,可以没有任何限制,可将没有关联关系的任意表进行连接。

这里拿学生表和班级表举例,在学生表中我们插入了20名学生的数据,课程表中插入三个班级。则学生和班级的笛卡尔结果就是将两表的每行数据一一组合,最后就是有 24 * 3 = 72 行的结果,如下图所示。

并且需要知道的是,下面学习的外连接,自连接,等值连接等都是在笛卡尔积的基础上筛选得到的。

对应的 SQL92 写法为:

select * from Student, Class;
mysql> select * from Student, Class;
+----+-----------+----------+-----+----------+----+----------+--------+---------------+
| id | name      | birth    | sex | class_id | id | name     | number | class_type_id |
+----+-----------+----------+-----+----------+----+----------+--------+---------------+
|  1 | 胡一      | 1994.1.1 | 男  |        1 |  1 | 1年1班   |      4 |             1 |
|  1 | 胡一      | 1994.1.1 | 男  |        1 |  3 | 1年2班   |      8 |             3 |
|  1 | 胡一      | 1994.1.1 | 男  |        1 |  5 | 1年3班   |     12 |             5 |
|  3 | 王阿      | 1992.1.1 | 女  |        1 |  1 | 1年1班   |      4 |             1 |
|  3 | 王阿      | 1992.1.1 | 女  |        1 |  3 | 1年2班   |      8 |             3 |
|  3 | 王阿      | 1992.1.1 | 女  |        1 |  5 | 1年3班   |     12 |             5 |
|  5 | 王琦      | 1993.1.2 | 男  |        1 |  1 | 1年1班   |      4 |             1 |
|  5 | 王琦      | 1993.1.2 | 男  |        1 |  3 | 1年2班   |      8 |             3 |
|  5 | 王琦      | 1993.1.2 | 男  |        1 |  5 | 1年3班   |     12 |             5 |
|  7 | 刘伟      | 1998.2.2 | 女  |        1 |  1 | 1年1班   |      4 |             1 |
|  7 | 刘伟      | 1998.2.2 | 女  |        1 |  3 | 1年2班   |      8 |             3 |
|  7 | 刘伟      | 1998.2.2 | 女  |        1 |  5 | 1年3班   |     12 |             5 |
| 11 | 张使      | 1994.1.1 | 男  |        3 |  1 | 1年1班   |      4 |             1 |
| 11 | 张使      | 1994.1.1 | 男  |        3 |  3 | 1年2班   |      8 |             3 |
| 11 | 张使      | 1994.1.1 | 男  |        3 |  5 | 1年3班   |     12 |             5 |
| 13 | 王阿      | 1992.1.1 | 女  |        3 |  1 | 1年1班   |      4 |             1 |
| 13 | 王阿      | 1992.1.1 | 女  |        3 |  3 | 1年2班   |      8 |             3 |
| 13 | 王阿      | 1992.1.1 | 女  |        3 |  5 | 1年3班   |     12 |             5 |
| 15 | 夏琪      | 1993.1.2 | 男  |        3 |  1 | 1年1班   |      4 |             1 |
| 15 | 夏琪      | 1993.1.2 | 男  |        3 |  3 | 1年2班   |      8 |             3 |
| 15 | 夏琪      | 1993.1.2 | 男  |        3 |  5 | 1年3班   |     12 |             5 |
| 17 | 刘表      | 1998.2.2 | 女  |        3 |  1 | 1年1班   |      4 |             1 |
| 17 | 刘表      | 1998.2.2 | 女  |        3 |  3 | 1年2班   |      8 |             3 |
| 17 | 刘表      | 1998.2.2 | 女  |        3 |  5 | 1年3班   |     12 |             5 |
| 19 | 诸葛      | 1994.1.1 | 男  |        3 |  1 | 1年1班   |      4 |             1 |
| 19 | 诸葛      | 1994.1.1 | 男  |        3 |  3 | 1年2班   |      8 |             3 |
| 19 | 诸葛      | 1994.1.1 | 男  |        3 |  5 | 1年3班   |     12 |             5 |
| 21 | 王前      | 1992.1.1 | 女  |        3 |  1 | 1年1班   |      4 |             1 |
| 21 | 王前      | 1992.1.1 | 女  |        3 |  3 | 1年2班   |      8 |             3 |
| 21 | 王前      | 1992.1.1 | 女  |        3 |  5 | 1年3班   |     12 |             5 |
| 23 | 王意识    | 1993.1.2 | 男  |        3 |  1 | 1年1班   |      4 |             1 |
| 23 | 王意识    | 1993.1.2 | 男  |        3 |  3 | 1年2班   |      8 |             3 |
| 23 | 王意识    | 1993.1.2 | 男  |        3 |  5 | 1年3班   |     12 |             5 |
| 25 | 刘等待    | 1998.2.2 | 女  |        3 |  1 | 1年1班   |      4 |             1 |
| 25 | 刘等待    | 1998.2.2 | 女  |        3 |  3 | 1年2班   |      8 |             3 |
| 25 | 刘等待    | 1998.2.2 | 女  |        3 |  5 | 1年3班   |     12 |             5 |
| 27 | 胡是一    | 1994.1.1 | 男  |        5 |  1 | 1年1班   |      4 |             1 |
| 27 | 胡是一    | 1994.1.1 | 男  |        5 |  3 | 1年2班   |      8 |             3 |
| 27 | 胡是一    | 1994.1.1 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 29 | 王阿请    | 1992.1.1 | 女  |        5 |  1 | 1年1班   |      4 |             1 |
| 29 | 王阿请    | 1992.1.1 | 女  |        5 |  3 | 1年2班   |      8 |             3 |
| 29 | 王阿请    | 1992.1.1 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
| 31 | 王消息    | 1993.1.2 | 男  |        5 |  1 | 1年1班   |      4 |             1 |
| 31 | 王消息    | 1993.1.2 | 男  |        5 |  3 | 1年2班   |      8 |             3 |
| 31 | 王消息    | 1993.1.2 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 33 | 刘全      | 1998.2.2 | 女  |        5 |  1 | 1年1班   |      4 |             1 |
| 33 | 刘全      | 1998.2.2 | 女  |        5 |  3 | 1年2班   |      8 |             3 |
| 33 | 刘全      | 1998.2.2 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
| 35 | 胡爱      | 1994.1.1 | 男  |        5 |  1 | 1年1班   |      4 |             1 |
| 35 | 胡爱      | 1994.1.1 | 男  |        5 |  3 | 1年2班   |      8 |             3 |
| 35 | 胡爱      | 1994.1.1 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 37 | 王表      | 1992.1.1 | 女  |        5 |  1 | 1年1班   |      4 |             1 |
| 37 | 王表      | 1992.1.1 | 女  |        5 |  3 | 1年2班   |      8 |             3 |
| 37 | 王表      | 1992.1.1 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
| 39 | 王华      | 1993.1.2 | 男  |        5 |  1 | 1年1班   |      4 |             1 |
| 39 | 王华      | 1993.1.2 | 男  |        5 |  3 | 1年2班   |      8 |             3 |
| 39 | 王华      | 1993.1.2 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 41 | 刘伟以    | 1998.2.2 | 女  |        5 |  1 | 1年1班   |      4 |             1 |
| 41 | 刘伟以    | 1998.2.2 | 女  |        5 |  3 | 1年2班   |      8 |             3 |
| 41 | 刘伟以    | 1998.2.2 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
| 43 | 胡一彪    | 1994.1.1 | 男  |        5 |  1 | 1年1班   |      4 |             1 |
| 43 | 胡一彪    | 1994.1.1 | 男  |        5 |  3 | 1年2班   |      8 |             3 |
| 43 | 胡一彪    | 1994.1.1 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 45 | 王阿符    | 1992.1.1 | 女  |        5 |  1 | 1年1班   |      4 |             1 |
| 45 | 王阿符    | 1992.1.1 | 女  |        5 |  3 | 1年2班   |      8 |             3 |
| 45 | 王阿符    | 1992.1.1 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
| 47 | 王琦删    | 1993.1.2 | 男  |        5 |  1 | 1年1班   |      4 |             1 |
| 47 | 王琦删    | 1993.1.2 | 男  |        5 |  3 | 1年2班   |      8 |             3 |
| 47 | 王琦删    | 1993.1.2 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 49 | 刘达达    | 1998.2.2 | 女  |        5 |  1 | 1年1班   |      4 |             1 |
| 49 | 刘达达    | 1998.2.2 | 女  |        5 |  3 | 1年2班   |      8 |             3 |
| 49 | 刘达达    | 1998.2.2 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
+----+-----------+----------+-----+----------+----+----------+--------+---------------+
72 rows in set (0.00 sec)

mysql> 

等值连接(内连接)

等值连接就是将两张表中都存在的列进行连接,具体来说就是 where 后面通过=进行筛选。

比如查询 Student 和其所属 Class 信息的关系:

SELECT * FROM Student as s, Class as c where s.class_id = c.id;
mysql> SELECT * FROM Student as s, Class as c where s.class_id = c.id;
+----+-----------+----------+-----+----------+----+----------+--------+---------------+
| id | name      | birth    | sex | class_id | id | name     | number | class_type_id |
+----+-----------+----------+-----+----------+----+----------+--------+---------------+
|  1 | 胡一      | 1994.1.1 | 男  |        1 |  1 | 1年1班   |      4 |             1 |
|  3 | 王阿      | 1992.1.1 | 女  |        1 |  1 | 1年1班   |      4 |             1 |
|  5 | 王琦      | 1993.1.2 | 男  |        1 |  1 | 1年1班   |      4 |             1 |
|  7 | 刘伟      | 1998.2.2 | 女  |        1 |  1 | 1年1班   |      4 |             1 |
| 11 | 张使      | 1994.1.1 | 男  |        3 |  3 | 1年2班   |      8 |             3 |
| 13 | 王阿      | 1992.1.1 | 女  |        3 |  3 | 1年2班   |      8 |             3 |
| 15 | 夏琪      | 1993.1.2 | 男  |        3 |  3 | 1年2班   |      8 |             3 |
| 17 | 刘表      | 1998.2.2 | 女  |        3 |  3 | 1年2班   |      8 |             3 |
| 19 | 诸葛      | 1994.1.1 | 男  |        3 |  3 | 1年2班   |      8 |             3 |
| 21 | 王前      | 1992.1.1 | 女  |        3 |  3 | 1年2班   |      8 |             3 |
| 23 | 王意识    | 1993.1.2 | 男  |        3 |  3 | 1年2班   |      8 |             3 |
| 25 | 刘等待    | 1998.2.2 | 女  |        3 |  3 | 1年2班   |      8 |             3 |
| 27 | 胡是一    | 1994.1.1 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 29 | 王阿请    | 1992.1.1 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
| 31 | 王消息    | 1993.1.2 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 33 | 刘全      | 1998.2.2 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
| 35 | 胡爱      | 1994.1.1 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 37 | 王表      | 1992.1.1 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
| 39 | 王华      | 1993.1.2 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 41 | 刘伟以    | 1998.2.2 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
| 43 | 胡一彪    | 1994.1.1 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 45 | 王阿符    | 1992.1.1 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
| 47 | 王琦删    | 1993.1.2 | 男  |        5 |  5 | 1年3班   |     12 |             5 |
| 49 | 刘达达    | 1998.2.2 | 女  |        5 |  5 | 1年3班   |     12 |             5 |
+----+-----------+----------+-----+----------+----+----------+--------+---------------+
24 rows in set (0.00 sec)

mysql>

非等值连接

非等值连接就是将等值连接中的等号换成其他的过滤条件。

比如这里查询每个班级的信息以及所属的班级类别。

SELECT * FROM Class as c, ClassType t where c.number between t.minimum_number and maximum_number;
mysql> SELECT * FROM Class as c, ClassType t where c.number between t.minimum_number and t.maximum_number;
+----+----------+--------+---------------+----+--------+----------------+----------------+
| id | name     | number | class_type_id | id | name   | minimum_number | maximum_number |
+----+----------+--------+---------------+----+--------+----------------+----------------+
|  1 | 1年1班   |      4 |             1 |  1 | 小班   |              1 |              4 |
|  3 | 1年2班   |      8 |             3 |  3 | 中班   |              5 |              8 |
|  5 | 1年3班   |     12 |             5 |  5 | 大班   |              9 |             12 |
+----+----------+--------+---------------+----+--------+----------------+----------------+
3 rows in set (0.00 sec)

mysql> 

外连接

对于 SQL92 的外连接来说,在连接时会将两张表分为主表和从表,主表显示所有的数据,从表显示匹配到的数据,没有匹配到的则显示 None。用+表示从表的位置。

左外连接:左表是主表,右表是从表

SELECT * FROM Student as s, Class as c where s.class_id = c.id(+);

右外连接:左表是从表,右表是主表

SELECT * FROM Class as c, Student as s where c.id = s.class_id(+);

注意 SQL92 中并没有全外连接。

自连接

自连接一般用于连接本身这张表,由于常见的 DBMS 都会对自连接做一些优化,所以一般在子查询和自连接的情况下都使用自连接。

比如想要查询比1年1班人数多的班级:

子查询:

SELECT * FROM Class WHERE number > (SELECT number FROM Class WHERE name="1年1班");

自连接:

SELECT c2.* FROM Class c1, Class c2 WHERE c1.number < c2.number and c1.name = "1年1班";
mysql> SELECT * FROM Class WHERE number > (SELECT number FROM Class WHERE name="1年1班");
+----+----------+--------+---------------+
| id | name     | number | class_type_id |
+----+----------+--------+---------------+
|  3 | 1年2班   |      8 |             3 |
|  5 | 1年3班   |     12 |             5 |
+----+----------+--------+---------------+
2 rows in set (0.00 sec)

mysql> SELECT c2.* FROM Class c1, Class c2 WHERE c1.number < c2.number and c1.name = "1年1班";
+----+----------+--------+---------------+
| id | name     | number | class_type_id |
+----+----------+--------+---------------+
|  3 | 1年2班   |      8 |             3 |
|  5 | 1年3班   |     12 |             5 |
+----+----------+--------+---------------+
2 rows in set (0.00 sec)

mysql> 

SQL99

交叉连接

SELECT * FROM Student CROSS JOIN Class;
SELECT * FROM Student CROSS JOIN Class CROSS JOIN ClassType;

还可以对多张表进行交叉连接,比如连接 Student,Class,ClassType 三张表,结果为 24 3 3 = 216 条。

相当于嵌套了三层 for 循环。

自然连接

其实就是 SQL92 中的等值连接,只不过连接的对象是具有相同列名,并且值也相同的内容。

SELECT * FROM Student NATURAL JOIN Class;
SELECT * FROM Student as s, Class as c where s.id = c.id;

如果想用NATURAL JOIN时,建议为两表设置相同的列名,比如 Student 表中的班级列为class_id,则在 Class 表中,id 也应改为class_id。这样连接更合理一些。

如果大家尝试,自然连接的话,会发现查出来的结果集为空,不要奇怪,下面说一下原因:

mysql> SELECT * FROM Student NATURAL JOIN Class;
Empty set (0.00 sec)

这是因为,NATURAL JOIN会自动连接两张表中相同的列名,而对于 Student 和 Class 两张表来说,id 和 name 在这两张表都是相同的,所以既满足 id 又满足 name 的行是不存在的。

相当于 SQL 变成了这样

SELECT * FROM Student as s, Class as c where s.id = c.id and s.name = c.name;

ON 连接

ON 连接其实对了 SQL92 中的等值连接和非等值连接:

等值连接:

SELECT * FROM Student as s JOIN Class as c ON s.class_id = c.id;

or

SELECT * FROM Student as s INNER JOIN Class as c ON s.class_id = c.id;

非等值连接:

SELECT * FROM Class as c JOIN ClassType t ON c.number between t.minimum_number and maximum_number;

USING 连接

NATURAL JOIN很像,可以手动指定具有相同列名的列进行连接:

SELECT * FROM Student JOIN Class USING(id);
mysql> SELECT * FROM Student JOIN Class USING(id);
+----+--------+----------+-----+----------+----------+--------+---------------+
| id | name   | birth    | sex | class_id | name     | number | class_type_id |
+----+--------+----------+-----+----------+----------+--------+---------------+
|  1 | 胡一   | 1994.1.1 | 男  |        1 | 1年1班   |      4 |             1 |
|  3 | 王阿   | 1992.1.1 | 女  |        1 | 1年2班   |      8 |             3 |
|  5 | 王琦   | 1993.1.2 | 男  |        1 | 1年3班   |     12 |             5 |
+----+--------+----------+-----+----------+----------+--------+---------------+
3 rows in set (0.00 sec)

mysql> 

这时就解决了之前列存在重名,无法连接的情况。

外连接

左外连接: 左表是主表,右表是从表

SELECT * FROM Student as s LEFT JOIN Class as c on s.class_id = c.id;
OR
SELECT * FROM Student as s LEFT OUTER JOIN Class as c on s.class_id = c.id;

右外连接:左表是从表,右表是主表

SELECT * FROM Student as s RIGHT JOIN Class as c on s.class_id = c.id;
OR
SELECT * FROM Student as s RIGHT OUTER JOIN Class as c on s.class_id = c.id;

全外连接: 左外连接 + 右外的连接的合集

SELECT * FROM Student as s FULL JOIN Class as c ON s.class_id = c.id;

MySQL 中没有全外连接的概念

自连接:

SELECT c2.* FROM Class c1 JOIN Class c2 ON c1.number < c2.number and c1.name = "1年1班";

SQL92 和 SQL99 的对比

  1. SQL92 中的等值连接(内连接),非等值连接,自连接对应了 SQL99 的 ON 连接,用于筛选满足连接条件的数据行。

  2. SQL92 的笛卡尔积连接,对应了 SQL99 的交叉连接。

  3. SQL92 中的外连接并不包含全外连接,而 SQL99 支持,并且将 SQL92 中 WHERE 换为 SQL99 的 ON。这样的好处可以更清晰的表达连接表的过程,更直观。

SELECT ...
FROM table1
    JOIN table2 ON filter_condition
        JOIN table3 ON filter_condition
  1. SQL99 多了自然连接和 USING 连接的过程,两者的区别是是否需要显式的指定列名。

总结

我们知道,在 SQL 中,按照年份划分了不同的标准,其中最为常用的是 SQL-92 和 SQL-99 两个标准。

接着,对比了 92 和 99 两者的不同,发现 99 的标准在连接时,更加符合逻辑并且更加直观。

转载至:https://www.cnblogs.com/michael9/p/13166575.html

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/04/01/join-patient-summary/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
关于 JOIN 耐心总结,学不会你打我系列
现在随着各种数据库框架的盛行,在提高效率的同时也让我们忽略了很多底层的连接过程,这篇文章是对 SQL 连接过程梳理,并涉及到了现在常用的 SQL 标准。 其实……
<<上一篇
下一篇>>
文章目录
关闭
目 录