PostgreSQL中的join
2019-01-05 本文已影响12人
三点水滴
join的概述
- 关联表(joined table)是根据一定规则将两张表合并在一起
- 一般join语法是:
T1 join_type T2 [join_condition]
- 所有类型的join都是可以链式的、嵌套的。
- 使用小括号可以控制关联的顺序
join的类型以及连接条件
从join的基本语法如下:
T1 { [INNER] | { left | right | full } [OUTTER]} JOIN T2 ON condition
T1 { [INNER] | { left | right | full } [OUTTER]} JOIN T2 USING(join_columns)
T1 NATURAL { [INNER] | { left | right | full } [OUTTER]} JOIN T2
由此可以知道join的类型有以下几种类型:
- 内连接(INNER JOIN)
- 左外连接(LEFT OUTTER JOIN)
- 右外连接(RIGHT OUTTER JOIN)
- 全外连接(FULL OUTTER JOIN)
- 自然连接(NATURAL JOIN)
举例说明
假设有以下两张表
Table A:
id | name |
---|---|
1 | Tom |
2 | Jerry |
3 | Mary |
Table B:
id | age |
---|---|
1 | 20 |
3 | 22 |
5 | 34 |
要说连接,首先要知道一个概念——笛卡尔积。
什么是笛卡尔积
在PostgreSQL中笛卡尔积就是cross join,这是上面join类型中没有提到的。
select * from t_a corss join t_b
结果如下:
id | name | id_1 | age |
---|---|---|---|
1 | Tom | 1 | 20 |
2 | Jerry | 1 | 20 |
3 | Mary | 1 | 20 |
1 | Tom | 3 | 22 |
2 | Jerry | 3 | 22 |
3 | Mary | 3 | 22 |
1 | Tom | 5 | 34 |
2 | Jerry | 5 | 34 |
3 | Mary | 5 | 34 |
简单来说,笛卡尔积就是把两张表所有的行拼起来。3行的表与3行的表连接,连接表就是9行。
内连接
内连接的 inner 是可以省略不写的。内连接会把满足连接条件的t_a和t_b的行连接起来,作为连接表的一行。
select * from t_a inner join t_b on t_a.id = t_b.id
结果如下:
id | name | id_1 | age |
---|---|---|---|
1 | Tom | 1 | 20 |
3 | Mary | 3 | 22 |
只有满足条件:id相等的列才会出现在连接表里。
左外连接
首先会执行内连接,然后把左表的行都放进连接表,对于没有满足条件的右表的行,用空值代替
select * from t_a left outter join t_b on t_a.id = t_b.id
结果如下:
id | name | id_1 | age |
---|---|---|---|
1 | Tom | 1 | 20 |
2 | Jerry | ||
3 | Mary | 3 | 22 |
右外连接
首先会执行内连接,然后把右表的行都放进连接表,对于没有满足条件的左表的行,用空值代替
select * from t_a right outter join t_b on t_a.id = t_b.id
结果如下:
id | name | id_1 | age |
---|---|---|---|
1 | Tom | 1 | 20 |
3 | Mary | 3 | 22 |
5 | 34 |
全外连接
首先会执行内连接,然后把左表和右表的行都放进连接表,对于没有满足条件的右表的行,用空值代替;对于没有满足条件的左表的行,用空值代替。
select * from t_a left outter join t_b on t_a.id = t_b.id
结果如下:
id | name | id_1 | age |
---|---|---|---|
1 | Tom | 1 | 20 |
2 | Jerry | ||
3 | Mary | 3 | 22 |
5 | 34 |
连接条件
on
on 后面只要跟上返回布尔值的条件表达式即可,没有强制要求一定要使用表中的列,类似于where条件。
using
using函数需要传入左表和右表都存在的列名。以上面的例子来说,
using(id)
等价于
on t_a.id = t_b.id
可以传入多个列名,就相当于用and连接多个条件。需要注意的点是:
- using中的列名必须是两张表同时存在的。
- 连接表中字段顺序是 using的参数字段,左表剩余字段,右表剩余字段。
select * from t_a inner join t_b using(id)
结果如下:
id | name | age |
---|---|---|
1 | Tom | 20 |
3 | Mary | 22 |
natural join
将natural join放在连接条件里而不是连接类型里面,主要是因为natural join是隐含的使用了using,并且参数是两张表中所有同名的列。
select * from t_a natural inner join t_b
结果如下:
id | name | age |
---|---|---|
1 | Tom | 20 |
3 | Mary | 22 |