暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

openGauss 连接操作

openGauss小助手 2021-10-27
1491

如果FROM关键字后有超过2个以上(含2个)的表参与连接操作,则该查询可以称为连接查询,也可以叫多表查询。

连接查询是SQL语言中最基本的操作,它的本质是多个表之间做笛卡儿积,借由这个思想又衍生出自然连接、θ连接等。

为了方便描述连接操作的结果,下面给出t1、t2、t3几个基本表以及它们的数据作为示例:

t1:

C1C2
12
1NULL
22

t2:

C1C2
12
11
NULL2

t3:

C1C2
11
12

通常的多表连接可以通过如下形式来实现,具体语句如下:

SELECT projection FROM t1, t2, t3… WHERE selection;

2-19t1、t2、t3三个表做连接操作,通过“,”间隔3个基本表t1、t2、t3,这3个表位于FROM关键字的后面,表示需要这3个表做连接操作,具体语句如下:

SELECT * FROM t1, t2, t3 WHERE t1.c1 = 0;

如果两个基本表确定做笛卡儿积操作,则可以在SQL中显式的指定做笛卡儿积的关键字。

2-20对表t1、t2做笛卡儿积,如图2-2所示。

图2-2 笛卡儿积示意图

具体语句如下:

SELECT * FROM t1 CROSS JOIN t2;

c1 | c2 | c1 | c2

----+----+----+----

1 | 2 | 1 | 2

1 | 2 | 1 | 1

1 | 2 | | 2

1 | | 1 | 2

1 | | 1 | 1

1 | | | 2

2 | 2 | 1 | 2

2 | 2 | 1 | 1

2 | 2 | | 2

(9 rows)

连接操作还能指定连接条件,如果连接条件中是等值条件,那么这种连接可以称为等值连接。

2-21对表t1、t2做等值内连接,如图2-3所示。

图2-3 等值内连接示意图

具体语句如下:

SELECT * FROM t1 INNER JOIN t2 ON t1.c1 = t2.c1;

c1 | c2 | c1 | c2

----+----+----+----

1 | 2 | 1 | 2

1 | 2 | 1 | 1

1 | | 1 | 2

1 | | 1 | 1

(4 rows)

在等值连接的基础上,还衍生出来一种新的连接方式:自然连接。如果进行连接的两个基本表中有相同的属性,那么自然连接会在这些相同的属性上自动做等值连接,而且会自动去掉重复的属性,而等值连接会保留两个表中重复的属性。

2-22对表t1、t2做自然连接,如图2-4所示。

图2-4 自然连接示意图

具体语句如下:

SELECT * FROM t1 NATURE JOIN t2;

c1 | c2

----+----

1 | 2

(1 row)

另外从连接结果的角度来划分,连接又可以分为内连接(Inner Join)、外连接(Outer Join)、半连接(Semi Join),如表2-7所示。

表2-7 基本表的数据组织形式

名称描述
内连接只有符合连接条件的结果才会作为最终的连接结果
外连接又可以分为左外连接(Left Outer Join)、右外连接(Right Outer Join)和全连接(Full Outer Join);
其中左外连接不但显式符合连接条件的结果,而且对于外表(左表)中不符合连接条件的元组也会生成连接结果,由于这些元组在内表(右表)中没有符合连接条件的元组,因此在投影时,对内表的投影为NULL值;
同理,右外连接显式的是内表(右表)中不符合连接条件的元组,全连接则同时显示内表(左表)和内表(右表)中的元组
半连接SQL语法中不能直接使用半连接,通常数据库的优化器会将连接条件中的子查询提升成连接操作,这时候连接的方式就是半连接;
基于连接条件谓词中是否含有否定谓词,半连接还可以分为Semi Join和Anti-Semi Join

2-23对表t1、t2做等值内连接,如图2-5所示。

图2-5 等值内连接示意图

具体语句如下:

SELECT * FROM t1 INNER JOIN t2 ON t1.c1 = t2.c1;

c1 | c2 | c1 | c2

----+----+----+----

1 | 2 | 1 | 2

1 | 2 | 1 | 1

1 | | 1 | 2

1 | | 1 | 1

(4 rows)

2-24对表t1、t2做等值左外连接,如图2-6所示。

图2-6 等值左外连接示意图

具体语句如下:

SELECT * FROM t1 LEFT JOIN t2 ON t1.c1 = t2.c1;

c1 | c2 | c1 | c2

----+----+----+----

1 | 2 | 1 | 2

1 | 2 | 1 | 1

1 | | 1 | 2

1 | | 1 | 1

2 | 2 | |

(5 rows)

2-25对表t1、t2做等值右外连接,如图2-7所示。

图2-7 等值右外连接示意图

具体语句如下:

SELECT * FROM t1 RIGHT JOIN t2 ON t1.c1 = t2.c1;

c1 | c2 | c1 | c2

----+----+----+----

1 | 2 | 1 | 2

1 | | 1 | 2

1 | 2 | 1 | 1

1 | | 1 | 1

| | | 2

(5 rows)

2-26对表t1、t2做等值全连接,如图2-8所示。

图2-8 等值全连接示意图

具体语句如下:

SELECT * FROM t1 FULL JOIN t2 ON t1.c1 = t2.c1;

c1 | c2 | c1 | c2

----+----+----+----

1 | 2 | 1 | 2

1 | 2 | 1 | 1

1 | | 1 | 2

1 | | 1 | 1

| | | 2

2 | 2 | |

(6 rows)

2-27对表t1、t2做Semi Join,对于t1中的每一个元组中的t1.c1,都去t2表中探测有没有和其相等的t2.c1,如果能找到就代表符合条件,和普通的连接不同的是,只要找到第一个和其相等的t2.c1就,就代表满足连接条件,如图2-9所示。

图2-9 Semi Join示意图

具体语句如下:

SELECT * FROM t1 WHERE t1.c1 IN (SELECT t2.c1 FROM T2);

QUERY PLAN

-----------------------------------------------------------------

Hash Semi Join

Hash Cond: (t1.c1 = t2.c1)

-> Seq Scan on t1

-> Hash

-> Seq Scan on t2

c1 | c2

----+----

1 | 2

1 |

(2 rows)

2-28对表t1、t2做Anti-Semi Join,和Semi Join相对应,t1.c1在t2表中只要找到一个相等的t2.c1,就不满足连接条件,如图2-10所示。

图2-10 Anti-Semi Join示意图

具体语句如下:

SELECT * FROM t1 WHERE t1.c1 NOT IN (SELECT t2.c1 FROM T2 WHERE t2.c1 IS NOT NULL);

QUERY PLAN

------------------------------------------------------------------------

Nested Loop Anti Join

Join Filter: ((t1.c1 = t2.c1) OR (t1.c1 IS NULL) OR (t2.c1 IS NULL))

-> Seq Scan on t1

-> Materialize

-> Seq Scan on t2

Filter: (c1 IS NOT NULL)

c1 | c2

----+----

2 | 2

(1 row)

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论