在 Postgres 上加入许多表的解决方案

Posted

技术标签:

【中文标题】在 Postgres 上加入许多表的解决方案【英文标题】:JOIN solution on Postgres with many tables 【发布时间】:2014-03-26 19:00:13 【问题描述】:

在 Acqua Data Studio 中管理的 Postgres 数据库的小问题:

我需要一种解决方案来创建一个将多个视图连接到一个表中的 SELECT。有10多个视图。 一个中心可能有多个 ID,一个 ID 可能有多个中心。因此,主表的 PK 将是中心 ID。

一个适用的例子(假设只存在3张表),如下:

视图1:

 central   |   ID   |    MAP
--------------------------------
    A      |   01   |    MAP1      
    A      |   02   |    MAP1
    A      |   03   |     -
    B      |   01   |    MAP3
    B      |   02   |     -
    C      |   01   |     -

视图2:

 central   |   ID   |    CAMEL
--------------------------------
    A      |   01   |    CAP1
    B      |   01   |    CAP1
    B      |   02   |    CAP2
    B      |   03   |    CAP3
    D      |   01   |     -  

视图3:

 central   |   ID   |    NRRG
--------------------------------
    A      |   01   |   NRRG2
    B      |   01   |     -
    C      |   01   |     -
    D      |   05   |   NRRG1

。 . .

结果表:

 central   |   ID   |    MAP    |  CAMEL  |  NRRG
--------------------------------------------------
    A      |   01   |    MAP1   |   CAP1  |  NRRG2
    A      |   02   |    MAP1   |         |  
    A      |   03   |     -     |         |
    B      |   01   |    MAP3   |   CAP1  |    -
    B      |   02   |     -     |   CAP2  |
    B      |   03   |           |   CAP3  |
    C      |   01   |     -     |         |    -
    D      |   01   |           |    -    |
    D      |   05   |           |         |  NRRG1

出现在 10 多个表中的任何一个中的任何 central-ID 都需要输入到串联表中。 我当然不关心那些没有对应到其他列的列上的空格...... 重要的是在每个 ID 中心行中获取其他表中存在的每个对应值。 PS:“-”是一个值!

我考虑过 FULL OUTER JOIN,但是参考手册中的参考资料我看不到完美的方法...

谢谢各位!

【问题讨论】:

。 .如果您发现其中一个适合您,您应该接受其中一个答案(我会选择使用 using 的版本,因为这样更优雅)。 【参考方案1】:

SQL Fiddle

select central, id, map, camel, nrrg
from
    v1
    full outer join
    v2 using (central, id)
    full outer join
    v3 using (central, id)
order by central, id
;
 central | id | map  | camel | nrrg  
---------+----+------+-------+-------
 A       |  1 | MAP1 | CAP1  | NRRG2
 A       |  2 | MAP1 |       | 
 A       |  3 |      |       | 
 B       |  1 | MAP3 | CAP1  | 
 B       |  2 |      | CAP2  | 
 B       |  3 |      | CAP3  | 
 C       |  1 |      |       | 
 D       |  1 |      |       | 
 D       |  5 |      |       | NRRG1

【讨论】:

+1 。 . .我没有意识到using 子句会保证列来自同一个表中的同一行。这很难用on 来表达。 “-”也会被退回吗?我还没有尝试过,但在你的结果中它们没有出现 @a_horse 我猜 Gordon 是在谈论 select 子句。但是 coalesce 是我们的朋友,只是更多的打字工作。 @a_horse 我也猜想合并是 using 对表格歧义所做的事情 @Zelda 在我的测试数据中,我将破折号替换为 null,因为您说这无关紧要。【参考方案2】:

当您有复合键时,完全外连接会更加复杂。而是使用union all/group by 方法:

select central, id, max(map) as map, max(camel) as camel, max(nrrg) as nrrg
from ((select central, id, map, null as camel, null as nrrg
       from view1
      ) union all
      (select central, id, null as map, camel, null as nrrg
       from view2
      ) union all
      (select central, id, null as map, null as camel, nrrg
       from view3
      )
     ) v
group by central, id;

【讨论】:

我会试试这个。外连接看起来真的很复杂!哈哈

以上是关于在 Postgres 上加入许多表的解决方案的主要内容,如果未能解决你的问题,请参考以下文章

关于 postgres 中的聚集索引

更新的Xubuntu,Postgres停止工作

来自多个表的 Postgres/netezza 多重连接

Postgres:更新所有表的主键序列

Postgres为连接表的array_agg返回[null]而不是[]

Spark Streaming 加入 GreenPlum/Postgres 数据。方法