繁体   English   中英

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

[英]PostgreSQL: Exclude geometries on the next query if it intersects on the previous one

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

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等于High 我还想获得与hazard值相交的几何数量: MediumLow 但是,如果某个几何图形已在High中相交,则将其排除在Medium查询之外,与Low相同的情况将排除那些在HighMedium相交的几何。

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

这是上面查询的示例结果: 在此处输入图片说明

预期结果应如下所示:

在此处输入图片说明

表格详情:

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和市政当局。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM