【问题标题】:Postgres - Insert nearest neighbour distance into another tablePostgres - 将最近邻距离插入另一个表
【发布时间】:2018-10-23 16:43:08
【问题描述】:

所以我有三个表(A、B、C)。在表 A 和 B 中,我有点,我想将 A 中的每一行插入到 C 中,以及从 B 到 A 中每个点的最近点的一些列,以及它们之间的距离。我知道获取最近邻居的查询是这样的:

SELECT DISTINCT ON (A.id5) A.state, B.way, st_distance (A.geom,B.geom) INTO C
FROM A, B   
WHERE ST_DWithin(A.geom, B.geom, 150)    
ORDER BY A.objectid, ST_Distance(A.geom,A.geom)

但我需要将其放入更大的 INSERT 查询中,并且我尝试这样做:

INSERT INTO complete(id_door, distance, id_way,Y, X, geom, check)
(SELECT A.state, (select distinct on (A.id5) ST_DISTANCE(A.geom,B.geom) from A order by A.id5, st_distance(A.geom,B.geom)), b.way, ST_Y(B.geom), ST_X(B.geom) ,B.geom, V.check
FROM A, B, C, V
WHERE
ST_INTERSECTS(A.geom, V.geom)\
AND ST_DWithin(A.geom, B.geom,150))

但这不是正确的方法,因为我得到了错误:

psycopg2.ProgrammingError: more than one row returned by a subquery used as an expression

我无法将所有距离从 A 和 B 复制到 C,然后删除除最近距离之外的所有距离,因为它是一个巨大的表,我会用完内存,所以我需要一种方法来只插入包含来自的信息的行从 B 到 A 的最近点。

我在这里做错了什么?提前谢谢你

更新:

经过一些帮助,我了解到我应该在 Select 查询中使用横向,但我不知道如何使用它。

我需要 Select 来获取表 A 中的每一行并从表 B 中找到它最近的邻居,我猜这是使用前面所述的查询完成的,然后将 A 中的一些列插入到表 C 中,从它最近的列中插入一些列邻居(表 B),以及表 V 中的一些列,这些列由相交条件选择。主要问题是如何将所有这些组织到 Select 中,这样我就不会出错。

这就是我现在所处的位置:

INSERT INTO C (id_door, distance, id_way,Y, X, geom, check)
(SELECT A.state, l.*, V.check
FROM A, B, C, V
lateral (select st_distance(a.geom,b.geom),  b.way, ST_Y(B.geom), ST_X(B.geom) ,B.geom
From B 
Where ST_DWithin(a.geom, b.geom,150))
Order by a.geom<->b.geom limit 1) l
WHERE
ST_INTERSECTS(A.geom, V.geom)

【问题讨论】:

  • 第二个查询的V表是什么?
  • 这只是我加入表格的一些附加信息,但与问题无关。
  • 好的,如果您从 A 中的点与 V 表中的许多对象相交,您会期待什么结果?你想从 V 中只选择一条记录(你想在这样的过滤器上实现什么条件)还是你想插入所有与 A 相交的记录?!?
  • V 表由不重叠的多边形组成,因此每个点只能与 V 中的一个对象重叠。如果不是这种情况,我将只设置一个插入限制多边形。如果我在更新中写的查询是正确的(是吗?),我猜我只需要在与 B 的距离之后添加另一个横向,对吗?谢谢你,Grzegorz
  • 查看最新版本的答案。我认为这可以满足您的需求。

标签: postgresql insert postgis


【解决方案1】:

您可以使用横向连接 - 非常智能的子查询类型,可以引用子查询之外的表。有关横向的更多信息,您可以找到here -- 根据答案中的新信息编辑 --

Insert into C (id_door, distance, id_way,Y, X, geom, check)
select l.*
  from a,
  lateral (select a.state, st_distance(a.geom,b.geom),
                  b.way, ST_Y(B.geom), ST_X(B.geom), B.geom,
                  v.check
             from b, v
            where ST_DWithin(a.geom, b.geom,150)
              and st_dwithin(a.geom,v.geom,0)
              and st_intersects(a.geom,v.geom)
            order by a.geom<->b.geom, v.geom limit 1) l

如果您希望 A 的每个点都有更多记录,则将限制从 1 增加到您想要的值。

【讨论】:

  • 非常感谢您的帮助,但我仍然不知道如何将其包含在 INSERT 查询中,因为我还必须从其他也有条件的表中执行 SELECT(WHERE)
  • 只需在from子句中添加另一个表并添加where条件就这么简单
  • 在您的插入中,您在 Select 部分使用了子查询(非常糟糕的做法),并且主查询中的每条记录在子查询中都有多个记录。在那种情况下,Postgres 不可能将类似的东西插入到表中。在 From 部分使用子查询(如果必须),并在 A 表和子查询中的记录之间的 where 子句中添加连接条件。最重要的是,在插入之前更新您的问题并显示数据结构和选择的预期结果将更容易为您提供正确的答案
  • 我刚刚更新了。希望您可以帮助组织选择查询。非常感谢,Grzegorz。
猜你喜欢
  • 2020-08-28
  • 1970-01-01
  • 2011-06-18
  • 2018-12-02
  • 2019-06-05
  • 1970-01-01
  • 2021-07-25
  • 2016-10-31
  • 2011-11-12
相关资源
最近更新 更多