簡體   English   中英

Postgresql Postgis SQL復雜聯接(但是不一定與GIS相關)

[英]Postgresql Postgis SQL Complex Join (not necessarily GIS related however)

抱歉,標題欠佳,但很難描述...

假設我有兩個表(cad和cad_polygon)...

cad和cad_polygon共享與另一個相關的同一列(cad_pid)...

cad具有以下列:cad_pid,jrsdctn_id

而cad_polygon具有以下列:cad_pid,ogc_fid,wkb_geometry

現在,我正在工作的以下查詢(半天嘗試)基於一個較長的經緯度坐標從小得多的多邊形子集中根據度數選擇一個宗地,它查找距給定的較長的經緯度坐標以米為單位的距離-ord,然后僅顯示質心在長而緯坐標500m以內的多邊形。

SELECT SUBQUERY.cad_pid, SUBQUERY.ogc_fid, SUBQUERY.dist_meters,
    SUBQUERY.wkb_geometry FROM (
    SELECT cad_pid, ogc_fid,
    CAST(ST_Distance_Sphere(
        ST_Centroid(wkb_geometry),
            ST_GeomFromText(
                'POINT(00.0000 -00.0000)',
            900914)
        ) AS numeric
    ) AS dist_meters, wkb_geometry
    FROM cad_polygon
    WHERE ST_DWithin(
        ST_Centroid(wkb_geometry),
        ST_GeomFromText(
            'POINT(00.0000 -00.0000)',
        900914),
    0.01)
    ORDER BY dist_meters ASC
) AS SUBQUERY
WHERE SUBQUERY.dist_meters < 500;

我想添加到此列表,並使用該查詢彈出的列表,加入其他表(cad),以便為每個結果行提供額外的列“ jrsdctn_id” ...即:

樣本數據為:cad:

cad_pid | jrsdctn_id
0001    | abc123
0002    | def456
0003    | dhk778
0004    | dsk730


cad_polygon:

cad_pid | ogc_fid | wkb_geometry
0001    | ht0101  | 67686687601010000200063D7987FF15ASD1518541DAW
0002    | hz4561  | 435453457601010000200063D7987FF15ASDFW4GF8DE4
0003    | yv0301  | 2626WD687601010000200063D7987FF15ASD1WE851D4D
0004    | vt9701  | D484DW4D8441D8W1C684V63D7987FF15ASD1D7DW4848D

預期成績:

cad_pid | jtsdctn_id | ogc_fid | dist_meters | wkb_geometry
0002    | def456     | hz4561  | 192.769     | 43545...
0004    | dsk730     | vt9701  | 342.548     | D484D...

如果有一些sql向導可以提供幫助,那就太好了!

有點晚了,當然,關於JOIN的公認答案是絕對正確的,但這實際上與GIS密切相關,並且它的意識最終使您更輕松了:

您似乎正在使用自定義CRS或ogr2ogr (或任何GDAL / OGR函數)在PostGIS的space_ref_sys表中找不到匹配的SRID /投影; 任何使用LonLat作為球面/類弧形代數輸入的PostGIS函數,都將始終假定您的坐標在EPSG:4326(WGS84)中。

如果您的LonLat與WGS84不完全匹配,結果將不正確

現在,PostGIS也具有地理類型,它再次假設EPSG:4326坐標,如果與這些功能一起使用,將隱式使用作為單位,如果與默認的ST_Distance參數一起使用,將在WGS84橢球體上進行計算(更精確,但比use_spheroid := false稍慢,后者將根據球體來計算距離)。

考慮到這一點,您的查詢可以表示為:

WITH
  pt AS (
    SELECT ST_Transform(ST_SetSRID(ST_MakePoint(0, 0), 900914), 4326)::geography AS geog
  ),

  ctr AS (
    SELECT *,
           ST_Transform(ST_Centroid(wkt_geometry), 4326)::geography AS geog
    FROM cad_polygon
  )

SELECT ctr.cad_pid,
       cad.jtsdctn_id,
       ctr.ogr_fid,
       ST_Distance(ctr.geog, pt.geog) AS distance_meter,
       ctr.wkt_geometry
FROM ctr
JOIN cad
  ON ctr.cad_pid = cad.cad_pid
WHERE ST_DWithin(ctr.geog, pt.geog, 500)
ORDER BY distance_meter ASC;

請注意,使用CTE可以避免為每個已處理的行進行轉換/廣播,並使其變得更加結構化。

我只是不能放手...

您可以使用JOIN

    SELECT SUBQUERY.cad_pid, SUBQUERY.ogc_fid, SUBQUERY.dist_meters,
        SUBQUERY.wkb_geometry, SUBQUERY.jrsdctn_id FROM (
        SELECT cad_pid, ogc_fid,
        CAST(ST_Distance_Sphere(
            ST_Centroid(wkb_geometry),
                ST_GeomFromText(
                    'POINT(00.0000 -00.0000)',
                900914)
            ) AS numeric
        ) AS dist_meters, wkb_geometry, cad.jrsdctn_id
        FROM cad_polygon
        INNER JOIN cad on cad.cad_pid = cad_polygon.cad_pid

        WHERE ST_DWithin(
            ST_Centroid(wkb_geometry),
            ST_GeomFromText(
                'POINT(00.0000 -00.0000)',
            900914),
        0.01)
        ORDER BY dist_meters ASC
    ) AS SUBQUERY
    WHERE SUBQUERY.dist_meters < 500;

或者最好在外部添加連接

SELECT SUBQUERY.cad_pid
        , SUBQUERY.ogc_fid
        , SUBQUERY.dist_meters,
        SUBQUERY.wkb_geometry, cad.jrsdctn_id 
    FROM (
        SELECT cad_polygon.cad_pid, ogc_fid,
        CAST(ST_Distance_Sphere(
            ST_Centroid(wkb_geometry),
                ST_GeomFromText(
                    'POINT(00.0000 -00.0000)',
                900914)
            ) AS numeric
        ) AS dist_meters
        , wkb_geometry
        FROM cad_polygon
        WHERE ST_DWithin(
            ST_Centroid(wkb_geometry),
            ST_GeomFromText(
                'POINT(00.0000 -00.0000)',
            900914),
        0.01)
        ORDER BY dist_meters ASC
    ) AS SUBQUERY
    INNER JOIN cad on cad.cad_pid = SUBQUERY.cad_pid
    WHERE SUBQUERY.dist_meters < 500;

暫無
暫無

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

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