总结一下数据分析中常用的联表查询方式。
什么是笛卡尔积?
笛卡尔积在数学上,是两个集合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 操作是常用操作,需要对其中的笛卡尔积有较好的理解。千万不要认为外连接查询返回的行数就是主表的行数!!!