连接查询

拿学生信息表与学生成绩表举例,之前的查询都没有完全查出两个表的信息;就算是用子查询去查询,也只是查询到的一个表的信息。若是将两张表的数据结合在一起,就能查到全部的信息,可是这样就会造成数据冗余的问题,再修改一个同学信息的时候也会修改多处,麻烦且容易出错。使用连接查询便可以解决这些问题。

连接的概念

连接的本质就是把各个表中的记录都取出来依次匹配的组合加入结果集并返回给用户。

将两个表的记录连起来组成新的更大的记录,这个查询过程称之为连接查询。

连接查询的结果集中包含一个表中的每一条记录与另一个表中的每一条记录相互匹配的组合,像这样的结果集就可以称之为笛卡尔积

  • 语法一
1
SELECT t1.m1, t1.n1, t2.m2, t2.n2 FROM t1, t2;
  • 语法二
1
SELECT m1, n1, m2, n2 FROM t1, t2;
  • 语法三
1
SELECT t1.*, t2.* FROM t1, t2;

连接过程简介

涉及单表的条件

之前也一直称为搜索条件,比如 t1.m1 > 1 是只针对 t1 表的过滤条件,t2.n2 < ‘d’是只针对 t2 表的过滤条件。

涉及两表的条件

比如 t1.m1 = t2.m2、t1.n1 > t2.n2 等,这些条件中涉及到了两个表。

内连接与外连接

内连接

对于内连接的两个表,驱动表中的记录在被驱动表中找不到匹配的记录,该记录不会加入到最后的结果集。

外连接

对于外连接的两个表,驱动表中的记录即使在被驱动表中没有匹配的记录,也仍然需要加入到结果集。

  • 左外连接 : 选取左侧的表为驱动表。

  • 右外连接 : 选取右侧的表为驱动表。

外连接中,通过 WHERE 子句与 ON 子句中的过滤条件实现自己想要的结果集。不符合WHERE子句中的过滤条件都不会被加入最后的结果集,ON子句中的查询条件若是没有被满足,也会被加入结果集中。

一般情况下,设计到单表中的过滤条件放到WHERE查询条件中,涉及到两表的过滤条件放到ON查询条件中。

放在ON子句中的过滤条件也称为连接条件

左外连接的语法

1
SELECT * FROM t1 LEFT [OUTER] JOIN t2 ON 连接条件 [WHERE 普通过滤条件];

t1为驱动表,t2为被驱动表,左右外连接必须使用ON子句来指出连接连接条件。

右连接的语法

1
SELECT * FROM t1 RIGHT [OUTER] JOIN t2 ON 连接条件 [WHERE 普通条件];

内连接的语法

内连接和外连接的根本区别就是在驱动表中的记录不符合 ON 子句中的连接条件时不会把该记录加入到最后的结果集。

1
SELECT * FROM t1 [INNER | CROSS] JOIN t2 [ON 连接条件] [WHERE 普通过滤条件];

MySQL 中,下边这几种内连接的写法都是等价的:

1
2
3
4
5
SELECT * FROM t1 JOIN t2;

SELECT * FROM t1 INNER JOIN t2;

SELECT * FROM t1 CROSS JOIN t2;

上边的这些写法和直接把需要连接的表名放到 FROM 语句之后,用逗号,分隔开的写法是等价的:

1
SELECT * FROM t1, t2;

推荐使用INNER JOIN的形式书写,语义明确。

多表连接

如果愿意,可以将多个表连接在一起查询:

1
SELECT * FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.m1 = t2.m2 AND t1.m1 = t3.m3;

自连接

同一个表也可以进行连接:

1
SELECT * FROM t1 AS table1, t1 AS table2;

需要设置别名才能查询,否则会报错。