簡體   English   中英

Postgresql-Postgis:對ID進行分組

[英]Postgresql-Postgis : grouping pairs of id

我使用Postgresql 9.6

我有一個包含數據行的表。 讓我們將其稱為TABLE1。 TABLE1有一個pkid列(一個串行主鍵)。

實際上,每一行都是一棟建築物,並且分組操作基於建築物之間是否相互接觸(DB具有PostGIS擴展名)。 現在,我的問題不是要檢測兩棟建築物何時相互接觸,而是要在臨時表中記錄這兩對建築物。

我使用SELECT子查詢(讓我們將其稱為subquery1)提取了它們的子集,我需要根據特定條件對它們進行分組。 Subquery1返回具有兩列pkid_bat1和pkid_bat2的一組行,這兩個表是關聯在一起的TABLE1的2個不同行的pkid(基於使用PostGIS函數的JOIN)。

我將以一個例子來說明一下:

假設我有3座彼此接觸的建築物:A,B和C。Subquery1將以pkid對的形式返回6行:AB,BA,AC,CA,BC,CB。

要記錄這3座建築物是關聯在一起的,實際上我只需要2對,例如:AB和AC。

所以到目前為止,我要做的是:在subquery1之后,我嵌套了另一個SELECT子查詢(subquery2),對於6行中的每行,將兩個pkid的最小值作為第一列返回,將第二個pkid的最大值作為第二列返回。兩個pkid並添加了DISTINCT子句。 因此,6行AB,BA,AC,CA,BC,CB變為​​3行:AB,AC,BC。

我仍然需要擺脫BC行。

在subquery2之后,我還有另一個嵌套的子查詢(subquery3),它對subquery2的結果進行自聯接:

SELECT mpb1.pkid_bat1 , mpb1.pkid_bat2
FROM resultsSubQuery2 AS mpb1
LEFT JOIN resultsSubQuery2 AS mpb2
ON mpb1.pkid_bat1 = mpb2.pkid_bat2
WHERE mpb2.pkid_bat2 IS NULL

這行得通:從AB,AC和BC行開始,它將僅保留AB和AC,因為A永遠不在pkid_bat2之內(由於在subquery2中使用了min和max函數)。 但這需要太多時間。

是否有另一種方法可以解決這種問題(創建pkid集)?


編輯:整個代碼在subquery2中進行了很小的更改,以在WHERE子句中更簡單地使用'<'來代替DISTINCT + min和max的使用:

WITH isolatedPonctualBuildings AS
(   
    SELECT DISTINCT ON (bat.pkid)
        bat.pkid, bat.pkid_emprise, bat.origine , bat.origine_id, bat.geom  
        FROM Temp_batiments_sites AS bat
        LEFT JOIN Temp_recoupements_bâtiments AS recoup
            ON bat.pkid = recoup.pkid_batiment2
        WHERE bat.type_geometry = 'Point'
        AND recoup.pkid IS NULL 
), 
matchedPonctualBuildings AS
( 
    SELECT 
        bat1.pkid AS pkid_bat1, 
        bat2.pkid AS pkid_bat2 
        FROM isolatedPonctualBuildings AS bat1
        JOIN isolatedPonctualBuildings AS bat2
            ON bat1.pkid_emprise = bat2.pkid_emprise 
            AND ST_Intersects (bat1.geom , bat2.geom) 
            AND ( bat1.origine != bat2.origine OR bat1.origine_id != bat2.origine_id )
        WHERE bat1.pkid < bat2.pkid 
)
    SELECT
        mpb1.pkid_bat1 , mpb1.pkid_bat2
        FROM matchedPonctualBuildings AS mpb1
        LEFT JOIN matchedPonctualBuildings AS mpb2
            ON mpb1.pkid_bat1 = mpb2.pkid_bat2
        WHERE mpb2.pkid_bat2 IS NULL

甚至很難,我敢肯定您最終會找到一個針對該問題的僅SQL解決方案(最有可能使用分層查詢),我認為使用過程邏輯來過濾多余的行要簡單得多。

應用程序中的簡單邏輯比嘗試卷積(非常慢)的SQL效率要高得多。

您只需要以簡單的有序方式檢索行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM