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
值相交的几何数:Medium
和 Low
。但是,如果某个几何图形已经在 High
中相交,则在其中排除 Medium
查询并且 Low
也排除那些在 High
和 Medium
中相交的几何图形.
我有这个想法,也许使用 CASE 或者我需要获取几何体的 id
然后在查询中尝试 NOT IN
但不知道如何去做。可能是因为我是 PostgreSQL 或任何数据库工作的新手。
下面是上述查询的示例结果:
预期的结果应该是这样的:
Table 详情:
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 中,您首先确定属于 "high" 危险类别的行,然后是 "medium" 危险类别中的行,但 EXCEPT
已经属于 "high" 类别,然后是 "low" 危险类别中的那些,但列为 "high" 或 "medium" 的除外。然后,在主查询中,您将 3 个 CTE 与每个 CTE 的子查询中计算的每个 barangay 和自治市的计数结合起来。 FULL JOIN
的使用使得在 "high" 危害 class 中没有建筑物的村镇和市政当局也会出现在结果中。
我有这个查询来获取与另一个几何相交的几何数:
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
值相交的几何数:Medium
和 Low
。但是,如果某个几何图形已经在 High
中相交,则在其中排除 Medium
查询并且 Low
也排除那些在 High
和 Medium
中相交的几何图形.
我有这个想法,也许使用 CASE 或者我需要获取几何体的 id
然后在查询中尝试 NOT IN
但不知道如何去做。可能是因为我是 PostgreSQL 或任何数据库工作的新手。
下面是上述查询的示例结果:
预期的结果应该是这样的:
Table 详情:
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 中,您首先确定属于 "high" 危险类别的行,然后是 "medium" 危险类别中的行,但 EXCEPT
已经属于 "high" 类别,然后是 "low" 危险类别中的那些,但列为 "high" 或 "medium" 的除外。然后,在主查询中,您将 3 个 CTE 与每个 CTE 的子查询中计算的每个 barangay 和自治市的计数结合起来。 FULL JOIN
的使用使得在 "high" 危害 class 中没有建筑物的村镇和市政当局也会出现在结果中。