[英]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的新手或任何數據庫工作。
預期結果應如下所示:
表格詳情:
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.