PostgreSQL 连接(JOIN)

Posted 瀚高PG实验室

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PostgreSQL 连接(JOIN)相关的知识,希望对你有一定的参考价值。

PostgreSQL 连接(JOIN)

PostgreSQL JOIN 子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段。
在 PostgreSQL 中,JOIN 有五种连接类型:

  1. CROSS JOIN :交叉连接
  2. INNER JOIN:内连接
  3. LEFT OUTER JOIN:左外连接
  4. RIGHT OUTER JOIN:右外连接
  5. FULL OUTER JOIN:全外连接

接下来让我们创建两张表 COMPANYDEPARTMENT

实例

创建 COMPANY 表,数据内容如下:

highgo=# select  * from  company ; 
 id | name | age |                       address                        | salary 
----+------+-----+------------------------------------------------------+--------
  1 | 张三 |  32 | 济南                                                 |  20000
  2 | 李四 |  25 | 青岛                                                 |  15000
  3 | 王五 |  23 | 北京                                                 |  20000
  4 | 赵六 |  25 | 上海                                                 |  65000
  5 | 小明 |  27 | 广州                                                 |  85000
  6 | 小红 |  22 | 深圳                                                 |  45000
  7 | 小强 |  24 | 成都                                                 |  10000
(7 行记录)

我们往表里添加几条数据:

INSERT INTO COMPANY_bak VALUES (8, '小磊', 24, '西安', 20000.00);
INSERT INTO COMPANY_bak VALUES (9, '小雷', 44, '武汉', 5000.00);
INSERT INTO COMPANY_bak VALUES (10, '小刚', 45, '杭州', 5000.00);

此时,COMPANY 表的记录如下:

 id | name | age |                       address                        | salary 
----+------+-----+------------------------------------------------------+--------
  1 | 张三 |  32 | 济南                                                 |  20000
  2 | 李四 |  25 | 青岛                                                 |  15000
  3 | 王五 |  23 | 北京                                                 |  20000
  4 | 赵六 |  25 | 上海                                                 |  65000
  5 | 小明 |  27 | 广州                                                 |  85000
  6 | 小红 |  22 | 深圳                                                 |  45000
  7 | 小强 |  24 | 成都                                                 |  10000
  8 | 小磊 |  24 | 西安                                                 |  20000
  9 | 小雷 |  44 | 武汉                                                 |   5000
 10 | 小刚 |  45 | 杭州                                                 |   5000
(10 行记录)

创建一张 DEPARTMENT 表,添加三个字段:

CREATE TABLE DEPARTMENT(
   ID INT PRIMARY KEY      NOT NULL,
   DEPT           CHAR(50) NOT NULL,
   EMP_ID         INT      NOT NULL);

向 DEPARTMENT 表插入三条记录:

INSERT INTO DEPARTMENT (ID, DEPT, EMP_ID)
VALUES (1, '技术支持', 1 );
INSERT INTO DEPARTMENT (ID, DEPT, EMP_ID)
VALUES (2, '研发', 2 );
INSERT INTO DEPARTMENT (ID, DEPT, EMP_ID)
VALUES (3, '财务', 7 );

此时,DEPARTMENT 表的记录如下:

 id |                          dept                          | emp_id 
----+--------------------------------------------------------+--------
  1 | 技术支持                                               |      1
  2 | 研发                                                   |      2
  3 | 财务                                                   |      7

交叉连接

交叉连接(CROSS JOIN)把第一个表的每一行与第二个表的每一行进行匹配。如果两个输入表分别有 x 和 y 行,则结果表有 x*y 行。
由于交叉连接(CROSS JOIN)有可能产生非常大的表,使用时必须谨慎,只在适当的时候使用它们。
下面是 CROSS JOIN 的基础语法:

SELECT ... FROM table1 CROSS JOIN table2 ...

基于上面的表,我们可以写一个交叉连接(CROSS JOIN),如下所示:

highgo=# SELECT EMP_ID, NAME, DEPT FROM COMPANY CROSS JOIN DEPARTMENT;

得到结果如下:

highgo=# SELECT EMP_ID, NAME, DEPT FROM COMPANY CROSS JOIN DEPARTMENT;
 emp_id | name |                          dept                          
--------+------+--------------------------------------------------------
      1 | 张三 | 技术支持                                              
      1 | 李四 | 技术支持                                              
      1 | 王五 | 技术支持                                              
      1 | 赵六 | 技术支持                                              
      1 | 小明 | 技术支持                                              
      1 | 小红 | 技术支持                                              
      1 | 小强 | 技术支持                                              
      1 | 小磊 | 技术支持                                              
      1 | 小雷 | 技术支持                                              
      1 | 小刚 | 技术支持                                              
      2 | 张三 | 研发                                                
      2 | 李四 | 研发                                                
      2 | 王五 | 研发                                                
      2 | 赵六 | 研发                                                
      2 | 小明 | 研发                                                
      2 | 小红 | 研发                                                
      2 | 小强 | 研发                                                
      2 | 小磊 | 研发                                                
      2 | 小雷 | 研发                                                
      2 | 小刚 | 研发                                                
      7 | 张三 | 财务                                                
      7 | 李四 | 财务                                                
      7 | 王五 | 财务                                                
      7 | 赵六 | 财务                                                
      7 | 小明 | 财务                                                
      7 | 小红 | 财务                                                
      7 | 小强 | 财务                                                
      7 | 小磊 | 财务                                                
      7 | 小雷 | 财务                                                
      7 | 小刚 | 财务                                                
(30 行记录)

内连接
内连接(INNER JOIN)根据连接谓词结合两个表(table1 和 table2)的列值来创建一个新的结果表。查询会把 table1 中的每一行与 table2 中的每一行进行比较,找到所有满足连接谓词的行的匹配对。
当满足连接谓词时,A 和 B 行的每个匹配对的列值会合并成一个结果行。
内连接(INNER JOIN)是最常见的连接类型,是默认的连接类型。
INNER 关键字是可选的。
下面是内连接(INNER JOIN)的语法:

SELECT table1.column1, table2.column2...
FROM table1
INNER JOIN table2
ON table1.common_filed = table2.common_field;

基于上面的表,我们可以写一个内连接,如下所示:

highgo=# SELECT EMP_ID, NAME, DEPT FROM COMPANY INNER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID;
 emp_id | name |                          dept                          
--------+------+--------------------------------------------------------
      1 | 张三 | 技术支持                                              
      2 | 李四 | 研发                                                
      7 | 小强 | 财务                                                
(3 行记录)

左外连接

外部连接是内部连接的扩展。SQL 标准定义了三种类型的外部连接: LEFT、RIGHT 和 FULL, PostgreSQL 支持所有这些。
对于左外连接,首先执行一个内连接。然后,对于表 T1 中不满足表 T2 中连接条件的每一行,其中 T2 的列中有 null 值也会添加一个连接行。因此,连接的表在 T1 中每一行至少有一行。
下面是左外连接( LEFT OUTER JOIN )的基础语法:

SELECT ... FROM table1 LEFT OUTER JOIN table2 ON conditional_expression ...

基于上面两张表,我们可以写个左外连接,如下:

highgo=# SELECT EMP_ID, NAME, DEPT FROM COMPANY LEFT OUTER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID;
SELECT EMP_ID, NAME, DEPT FROM COMPANY_bak LEFT OUTER JOIN DEPARTMENT ON COMPANY_bak.ID = DEPARTMENT.EMP_ID;
 emp_id | name |                          dept                          
--------+------+--------------------------------------------------------
      1 | 张三 | 技术支持                                              
      2 | 李四 | 研发                                                
      7 | 小强 | 财务                                                
        | 小刚 | 
        | 小明 | 
        | 小磊 | 
        | 小红 | 
        | 赵六 | 
        | 王五 | 
        | 小雷 | 
(10 行记录)

右外连接

首先,执行内部连接。然后,对于表T2中不满足表T1中连接条件的每一行,其中T1列中的值为空也会添加一个连接行。这与左联接相反;对于T2中的每一行,结果表总是有一行。
下面是右外连接( RIGHT OUT JOIN)的基本语法:

SELECT ... FROM table1 RIGHT OUTER JOIN table2 ON conditional_expression ...

基于上面两张表,我们建立一个右外连接:

highgo=# SELECT EMP_ID, NAME, DEPT FROM COMPANY RIGHT OUTER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID;
 emp_id | name |                          dept                          
--------+------+--------------------------------------------------------
      1 | 张三 | 技术支持                                              
      2 | 李四 | 研发                                                
      7 | 小强 | 财务                                                
(3 行记录)

外连接

首先,执行内部连接。然后,对于表 T1 中不满足表 T2 中任何行连接条件的每一行,如果 T2 的列中有 null 值也会添加一个到结果中。此外,对于 T2 中不满足与 T1 中的任何行连接条件的每一行,将会添加 T1 列中包含 null 值的到结果中。
下面是外连接的基本语法:

SELECT ... FROM table1 FULL OUTER JOIN table2 ON conditional_expression ...

基于上面两张表,可以建立一个外连接:

highgo=# SELECT EMP_ID, NAME, DEPT FROM COMPANY FULL OUTER JOIN DEPARTMENT ON COMPANY.ID = DEPARTMENT.EMP_ID;
  emp_id | name |                          dept                          
--------+------+--------------------------------------------------------
      1 | 张三 | 技术支持                                              
      2 | 李四 | 研发                                                
      7 | 小强 | 财务                                                
        | 小刚 | 
        | 小明 | 
        | 小磊 | 
        | 小红 | 
        | 赵六 | 
        | 王五 | 
        | 小雷 | 
(10 行记录)

以上是关于PostgreSQL 连接(JOIN)的主要内容,如果未能解决你的问题,请参考以下文章

INNER JOIN 与 h2 数据库和 postgresql 数据库的区别

9.PostgreSQL的Join,Union,Null

跟我一起读postgresql源码(十三)——Executor(查询执行模块之——Join节点(上))

Postgresql left join左连接后数据变多去重记录(当左表1对多右表时)

PostgreSQL 查询到 JOIN 和 SUM

在 Join PostgreSQL 中取消嵌套数组