PostgreSQL:如果下一个查询与前一个查询相交,则排除下一个查询的几何图形

标签 postgresql postgis

我有这个查询来获取与另一个几何相交的几何数:

SELECT  count(evidensapp_polystructures.brgy_locat) AS high,
        evidensapp_polystructures.brgy_locat AS barangay,
        evidensapp_polystructures.municipali AS municipality
FROM evidensapp_floodhazard
INNER JOIN evidensapp_polystructures
      ON st_intersects(evidensapp_floodhazard.geom, evidensapp_polystructures.geom) 
      AND evidensapp_floodhazard.hazard= 'High'
GROUP BY evidensapp_polystructures.brgy_locat, evidensapp_polystructures.municipali;

如您所见,它的危险 等于我还想获得与 hazard 值相交的几何数:MediumLow。但是,如果某个几何图形已经在 High 中相交,则在其中排除 Medium 查询,同样适用于 Low 排除那些在 中相交的几何图形>高

我有这个想法,也许用CASE或者我需要获取几何体的 id 然后在查询中尝试 NOT IN 但不知道该怎么做。可能是因为我是 PostgreSQL 或任何数据库工作的新手。

以下是上述查询的示例结果: enter image description here

预期的结果应该是这样的:

enter image description here

表格详细信息:

CREATE TABLE evidensapp_floodhazard (
  id serial NOT NULL,
  hazard character varying(6) NOT NULL,
  date_field character varying(60),
  geom geometry(MultiPolygon,32651),
  CONSTRAINT evidensapp_floodhazard_pkey PRIMARY KEY (id)
);

CREATE INDEX evidensapp_floodhazard_geom_id
  ON evidensapp_floodhazard USING gist (geom);

ALTER TABLE evidensapp_floodhazard CLUSTER ON evidensapp_floodhazard_geom_id;

CREATE TABLE evidensapp_polystructures (
  id serial NOT NULL,
  bldg_name character varying(100) NOT NULL,
  bldg_type character varying(50) NOT NULL,
  brgy_locat character varying(50) NOT NULL,
  municipali character varying(50) NOT NULL,
  province character varying(50) NOT NULL,
  geom geometry(MultiPolygon,32651),
  CONSTRAINT evidensapp_polystructures_pkey PRIMARY KEY (id)
);

CREATE INDEX evidensapp_polystructures_geom_id
  ON evidensapp_polystructures USING gist (geom);

ALTER TABLE evidensapp_polystructures CLUSTER ON evidensapp_polystructures_geom_id;

最佳答案

由于在比较方面您对字符串“High”、“Medium”和“Low”几乎无能为力,因此您必须使用子查询。具有一些 CTE 的解决方案可能是最干净的:

WITH hi AS (
  SELECT ps.id, ps.brgy_locat, ps.municipali
  FROM evidensapp_polystructures ps
  JOIN evidensapp_floodhazard fh ON fh.hazard = 'High'
                                 AND ST_Intersects(fh.geom, ps.geom)
), med AS (
  SELECT ps.id, ps.brgy_locat, ps.municipali
  FROM evidensapp_polystructures ps
  JOIN evidensapp_floodhazard fh ON fh.hazard = 'Medium'
                                 AND ST_Intersects(fh.geom, ps.geom)
  EXCEPT SELECT * FROM hi
), low AS (
  SELECT ps.id, ps.brgy_locat, ps.municipali
  FROM evidensapp_polystructures ps
  JOIN evidensapp_floodhazard fh ON fh.hazard = 'Low'
                                 AND ST_Intersects(fh.geom, ps.geom)
  EXCEPT SELECT * FROM hi
  EXCEPT SELECT * FROM med
)
SELECT brgy_locat AS barangay, municipali AS municipality, high, medium, low
FROM (SELECT brgy_locat, municipali, count(*) AS high
      FROM hi
      GROUP BY 1, 2) cnt_hi
FULL JOIN (SELECT brgy_locat, municipali, count(*) AS medium
      FROM med
      GROUP BY 1, 2) cnt_med USING (brgy_locat, municipali)
FULL JOIN (SELECT brgy_locat, municipali, count(*) AS low
      FROM low
      GROUP BY 1, 2) cnt_low USING (brgy_locat, municipali);

在三个 CTE 中,您首先确定属于“高”危险类别的行,然后确定属于“中”危险类别的行,但 EXCEPT 那些已经属于“高”类别的行,然后是“低”危险类别中的那些,但列为“高”或“中”的除外。然后,在主查询中,您将 3 个 CTE 与每个 CTE 的子查询中计算的每个 barangay 和自治市的计数结合起来。使用 FULL JOIN,这样在“高”危险类别中没有结构的 barangays 和市政当局也会出现在结果中。

关于PostgreSQL:如果下一个查询与前一个查询相交,则排除下一个查询的几何图形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31779258/

相关文章:

database - 在(postgresql)数据库中存储 EUI-64 地址的数据类型

python - 使用按查询排序的无序结果

database - PostgreSQL 的可扩展性

postgresql - JPA 3 Hibernate + PostgreSQL 9.6.3 查询中出现限制错误

java - 这是检查 Postgres 是否提交事务 id 的正确方法吗

sql - 在 postgresql 中创建一个父项或一组父项的所有子项的表

sql - 许多相交的 ST_ExteriorRing(圆)上的 ST_Union()与 ST_Node(ST_Collect())

防止 SQL 注入(inject)的 PostgreSQL 美元引号字符串常量

postgresql - 如何使用 Postgis 查找我所在城市的所有街道交叉口

postgresql - Postgis + boost::geometry + C++