计算两个表之间的距离

时间:2021-02-11 14:10:58

标签: sql postgresql postgis

我的 PostgreSQL 数据库触发器有问题。

我正在尝试使用 PostGIS 工具计算两个地理点之间的距离。 这两个点在单独的表中,这两个表之间的 KEY 是 site_id 列。

sites 表结构是:

CREATE TABLE sites(
  site_id INT,
  site_name text,
  latitude float ( 6 ),
  longitude float ( 6 ),
  geom geometry

);

dots 表结构是:

CREATE TABLE dots(
  dot_id INT,
  site_id INT,
  latitude float ( 6 ),
  longitude float ( 6 ),
  rsrp float ( 6 ),
  dist INT,
  project_id INT,
  dist_from_site INT,
  geom geometry,
  dist_from_ref INT;
);

目标是创建一个触发器,在添加新点时自动计算距离。

我创建的触发器是:

CREATE TRIGGER dots_insert_site_dist_trigger
  AFTER UPDATE OF "geom"
  ON "dots"
  FOR EACH ROW
  EXECUTE PROCEDURE dots_insert_site_dist_update();``

函数本身:

  RETURNS trigger 
  AS
$$
BEGIN
        UPDATE dots SET dist_from_site =
  (SELECT ROUND(100*ST_Distance(NEW.geom, sites.geom))
  FROM
  dots,
  sites
  WHERE sites.site_id = NEW.site_id);
  RETURN NEW;
END;
$$
 LANGUAGE 'plpgsql';

错误:

<块引用>

错误:用作表达式的子查询返回多于一行 上下文:SQL 语句“UPDATE dots SET dist_from_site = (SELECT ROUND(100*ST_Distance(NEW.geom,sites.geom)) 从 点, 网站 WHERE sites.site_id = NEW.site_id)" PL/pgSQL 函数 dots_insert_site_dist_update() 第 3 行在 SQL 语句

站点表: 1

点表: 2

1 个答案:

答案 0 :(得分:1)

乍一看似乎您错过了子查询中的连接条件

SELECT ROUND(100*ST_Distance(NEW.geom, sites.geom))
FROM  dots
INNER JOIN sites on dots site_id = sites.site_id
WHERE sites.site_id = NEW.site_id

这应该生成一个笛卡尔积(表之间的 m x n 行.. 建议您避免使用基于逗号分隔表名和 where 条件的旧连接语法,并使用带有 on 子句的显式连接语法

你可以尝试使用查询作为更新的 subqiery

  UPDATE dots 
  SET dist_from_site = t.my_dist
  FROM (
      SELECT dots.site_id, ROUND(100*ST_Distance(dots.geom, sites.geom)) my_dist
      FROM  dots 
      INNER JOIN sites on dots.site_id = sites.site_id 
      WHERE sites.site_id = dots.site_id
  ) t 
  WHERE dots.site_id = t.site_id