【问题标题】:Combining tables where some keys are in common and some are missing组合一些键相同而一些键缺失的表
【发布时间】:2015-06-26 15:44:53
【问题描述】:

我的 postgres 数据库(9.3 版)中有一个土地覆盖值表。键值为“huc12code”,表示空间区域。这是土地覆盖表的第一个条目(它有 1700 多行):

 huc12code   | open_water  |  developed  | bare_earth  |  managed | heritage
030402080205 |    0.107027 |   0.0215444 |    0.406911 |          |

管理和遗产土地的面积在此表中为空,但存储在单独的表中。他们还将huc12code 作为第一列:

来自temp_heritage 表:

 huc12code   |  heritage
-------------+-------------
030101020801 |   0.0402684

来自temp_managed 表:

 huc12code   |   managed
-------------+------------- 
030101020802 | 0.000385026

我想将管理和遗产字段合并到我的土地覆盖表中,但我发现两个问题:

  1. landcover 表中的大部分huc12code 字段都可以在temp_managedtemp_heritage 中找到,但有些不是。这是因为“临时”表不包括 heritagemanaged 字段等于 0 的地方。

  2. 我确实希望 landcover 表包含一个 0 值,其中 heritagemanaged 字段为 0,但由于这些值实际上并不存在于“临时”表中,我需要一些逻辑为huc12code 中的每个huc12code 插入零的heritage 字段,但不在temp_heritage 中(对于管理字段也是如此)。

【问题讨论】:

  • 左外连接也是如此,然后使用 COALESCE 将这些列中的空值替换为默认值(零或其他)。
  • 这似乎可以查询我要插入的列:SELECT coalesce(temp_heritage.heritage,0) FROM landcover LEFT JOIN temp_heritage ON landcover.huc12code = temp_heritage.huc12code;
  • 如何结合INSERT INTO命令,将结果插入到landcover中?我对那个命令没有太多经验,我不想搞砸我的土地覆盖表。

标签: sql postgresql sql-update


【解决方案1】:

假设huc12code 在所有表中唯一

仅更新值可用的行

要在单个UPDATE 中完成所有操作,请使用FULL [OUTER] JOIN 连接两个源表以保留所有行。然后在UPDATE 命令的FROM 子句中使用它:

UPDATE landcover l
SET    managed  = COALESCE(t.managed, 0) 
     , heritage = COALESCE(t.heritage, 0) 
FROM (
   SELECT huc12code, m.managed, h.heritage
   FROM   temp_managed m
   FULL   JOIN temp_heritage h USING (huc12code)
   ) t
WHERE l.huc12code = t.huc12code;

如果源中有(组合)行,landcover 中的每一行都会只更新一次。其余的根本没动。

更新所有

改用两个LEFT JOIN

UPDATE landcover l
SET    managed  = COALESCE(t.managed, 0) 
     , heritage = COALESCE(t.heritage, 0) 
FROM (
   SELECT l.huc12code, m.managed, h.heritage
   FROM   landcover l
   LEFT   JOIN temp_managed  m USING (huc12code)
   LEFT   JOIN temp_heritage h USING (huc12code)
   ) t
WHERE l.huc12code = t.huc12code;

没有源或源 NULL 值的列设置为 0

【讨论】:

  • 这不太奏效....该命令没有发出错误(它只是声明:UPDATE 1620)。但是土地覆盖的遗产和管理领域仍然是空的
  • 实际上,从头开始。这些列并不完全是空的。它们有很长的空部分,然后是长的零部分和带有实际数据的长部分。我将删除此表,然后重新创建我原来的土地覆盖表。
  • @MeganMallard:这不是问题。只需定义是否要保留或更新 landcover 中的现有值。
  • 更新所有行解决方案有效。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-01
  • 2015-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-31
相关资源
最近更新 更多