【问题标题】:Join two tables in Postgresql while keeping non-matching rows在 Postgresql 中加入两个表,同时保留不匹配的行
【发布时间】:2018-06-14 20:35:56
【问题描述】:

我正在尝试使用 PostGIS 扩展将空间表与 Postgresql 中的非空间表连接起来。

空间表:

geom   | attribute1 | Key |
foobar | foobar     |  1  |
foobar | foobar     |  2  |
foobar | foobar     |  3  |
foobar | foobar     |  4  |

非空间表:

attribute2 | attribute3 | Key |
foobar     | foobar     |  1  |
foobar     | foobar     |  4  |

joined_table:

geom   | attribute1 | Key | attribute2 | attribute3 |
foobar | foobar     |  1  | foobar     | foobar     |
foobar | foobar     |  2  | NULL       | NULL       |
foobar | foobar     |  3  | NULL       | NULL       |
foobar | foobar     |  4  | foobar     | foobar     |

NULL 我的意思是空的。

以下代码有效:

CREATE TABLE joined_table AS
SELECT *
FROM spatial_table
JOIN non_spatial_table ON spatial_table.title_no = non_spatial_table.title_number;

但是,spatial_table 中不等于 non_spatial_table 的所有行都被排除在结果表之外。

结果表:

geom   | attribute1 | Key | attribute2 | attribute3 |
foobar | foobar     |  1  | foobar     | foobar     |
foobar | foobar     |  4  | foobar     | foobar     | 

我也试过了:

ALTER TABLE spatial_table
    ADD COLUMN title_number varchar,
    ADD COLUMN tenure varchar
UPDATE spatial_table
    SET title_number = non_spatial_table.title_number
FROM spatial_table INNER JOIN non_spatial_table ON spatial_table.title_no = non_spatial_table.title_number

但是我收到以下错误:

ERROR: table name "spatial_table" specified more than once SQL state: 42712

有谁知道我怎样才能实现这种类型的加入?

【问题讨论】:

  • 为表格添加一些别名,并参考这些。 , 并添加一些分号。另外:您不必在 FROM 子句中重复 target 表。

标签: postgresql join sql-update postgis


【解决方案1】:

你想要一个LEFT OUTER JOIN。我只用 varchar 字段模拟了这个例子(空间部分在这里无关紧要),加入关键字段。

postgres@sandbox=# select * from spatial_table;
 key |  geom   | attribute1
-----+---------+------------
   1 | foobar1 | foobar1
   2 | foobar2 | foobar2
   3 | foobar3 | foobar3
   4 | foobar4 | foobar4
(4 rows)

postgres@sandbox=# select * from non_spatial_table;
 key | attribute2 | attribute3
-----+------------+------------
   1 | foobar12   | foobar13
   4 | foobar42   | foobar43
(2 rows)

postgres@sandbox=# select a.geom, a.attribute1, a.key, b.attribute2, b.attribute3
sandbox-# from spatial_table a
sandbox-# left outer join non_spatial_table b
sandbox-# on a.key=b.key;
  geom   | attribute1 | key | attribute2 | attribute3
---------+------------+-----+------------+------------
 foobar  | foobar1    |   1 | foobar12   | foobar13
 foobar2 | foobar2    |   2 | [NULL]     | [NULL]
 foobar3 | foobar3    |   3 | [NULL]     | [NULL]
 foobar4 | foobar4    |   4 | foobar42   | foobar43
(4 rows)

只需在 CTAS 中使用最后一个查询(也许视图或物化视图更有意义)。

【讨论】:

    【解决方案2】:

    我尝试了 Don Seilers 解决方案,如下所示:

    SELECT a.geom, a.title_no, b.title_number, b.tenure
    FROM spatial_table a
    LEFT OUTER JOIN non_spatial_table b
    ON a.title_no = b.title_number;
    

    它运行,但随后内存不足。我增加了 postgresql.conf 中的 work_mem 和共享缓冲区,但没有效果。有没有办法让上面的代码更有效率,还是我在 postgresql.conf 设置中遗漏了什么?

    更新:上面的代码有效,内存问题原来是一个完全不同的问题。

    【讨论】:

    • 你的桌子有多大?不知道为什么你会用完内存。确保您加入的字段也都已编入索引。
    猜你喜欢
    • 2017-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多