总结一下数据分析中常用的联表查询方式。

什么是笛卡尔积?

笛卡尔积在数学上,是两个集合X和Y的笛卡尔积(Cartesian product),又称直积。

在 SQL 查询中,笛卡尔积又叫 [cross] join,是两表连接的一种方式。

假设表A和表B的数据如下所示:

表A 表B
id id
1 1
0 0
1 0
3 2

执行以下语句后

SELECT a.id, b.id FROM table_a AS a cross join table_b AS b;
a_id b_id
1 1
1 0
1 0
1 2
0 1
0 0
0 0
0 2
1 1
1 0
1 0
1 2
3 1
3 0
3 0
3 2

即 A 表所有元素与 B 表所有元素进行组合。假设 A 表的行数为 m,B 表的行数为 n,则返回的行数为 m*n。

1. 内连接

内连接 INNER JOIN 是最常用的连接操作。求左右两张表的交集,从笛卡尔积中挑出ON子句条件成立的记录。也可以直接写作 JOIN 。

同样是上面的例子,执行以下语句后

SELECT a.id, b.id FROM table_a AS a inner join table_b AS b ON a.id=b.id;

查询结果如下:

a_id b_id
1 1
1 0
1 0
1 2
0 1
0 0
0 0
0 2
1 1
1 0
1 0
1 2
3 1
3 0
3 0
3 2

查询返回的结果只有 4 条。因为 A 表在连接时的重复 key 值为2条,B表在连接时重复的 key 值为 2 条记录,因此总共查询返回 4 条。

2. 外连接

外连接可以分为左连接和右连接。左右是根据主表在连接时的位置而定的。

2.1 左连接

左连接即左表为主表。左连接是求主表和另一张表的交集外加主表剩下的数据。从笛卡尔积的角度讲,就是先从笛卡尔积中挑出ON子句条件成立的记录,然后加上左表——主表中剩余的记录。

有一些博客说左连接返回的行数和左表行数一致不完全正确,这种情况仅限于左右表连接时的key值唯一。

左连接可以写作 LEFT [OUTER] JOIN,即 OUTER 可以省略。

执行以下 SQL 查询语句后

SELECT a.id, b.id FROM table_a AS a left outer join table_b AS b ON a.id=b.id;
a_id b_id
1 1
0 0
0 0
1 1
3 NULL

最后一行即为左表剩余的记录

2.2 右连接

右连接即右表为主表。右连接同样是求主表和另一张表的交集外加主表剩下的数据,只是这时的主表是右表。从笛卡尔积的角度来说,就是先从笛卡尔积中挑出ON子句条件成立的记录,然后加上右表——主表中剩余的记录。

右连接可以写作 RIGHT [OUTER] JOIN,同样可以省略 OUTER。

执行以下 SQL 查询语句后

SELECT a.id, b.id FROM table_a AS a right outer join table_b AS b ON a.id=b.id;
a_id b_id
1 1
0 0
0 0
1 1
NULL 2

最后一行即为右表剩余的记录。

3. 全连接

FULL OUTER JOIN,返回左右表中的所有记录。从笛卡尔积的角度来讲,就是从笛卡尔积中挑出ON子句条件成立的记录,然后加上左表和右表剩余的记录。

执行以下 SQL 查询语句后

SELECT a.id, b.id FROM table_a AS a full outer join table_b AS b ON a.id=b.id;
a_id b_id
1 1
0 0
0 0
1 1
3 NULL
NULL 2

总结

SQL 中多表查询 JOIN 操作是常用操作,需要对其中的笛卡尔积有较好的理解。千万不要认为外连接查询返回的行数就是主表的行数!!!