Postgresql Postgis SQL Complex Join(但不一定与 GIS 相关)
Postgresql Postgis SQL Complex Join (not necessarily GIS related however)
抱歉 lack-lustre 标题,但很难描述...
假设我有两个 table(cad 和 cad_polygon)...
cad 和 cad_polygon 共享与 one-another (cad_pid)...
相关的同一列
cad 有这些列:cad_pid、jrsdctn_id
而 cad_polygon 有这些列:cad_pid、ogc_fid、wkb_geometry
现在,我正在处理的以下查询(尝试了半天)根据经纬度 co-ord 的度数选择一个地块,从那个明显更小的多边形子集中,它找到它们的距离(以米为单位)从给定的 long,lat co-ord,然后仅显示质心在 long,lat co-ord.
500 米以内的多边形
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;
我想添加到这个并使用这个查询吐出的列表,加入我的另一个 table (cad) 这样我就可以为每个结果行提供额外的列 "jrsdctn_id".. . 即:
示例数据为:
加元:
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
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;
有点晚了,接受的答案关于 JOIN
当然是绝对正确的,但这实际上与 GIS 有很大关系,它的意识最终使事情对你来说更容易:
您似乎正在使用自定义 CRS 或 ogr2ogr(或任何 GDAL/OGR 函数)在 PostGIS 中未找到匹配的 SRID/projection spatial_ref_sys table;但是,任何使用 LonLat 作为 spherical/shperoidal 代数输入的 PostGIS 函数都将始终假定您的坐标在 EPSG:4326 (WGS84).
中
如果您的 LonLat 与 WGS84 的 不完全 匹配,结果将会关闭!
现在,PostGIS 也有 geography 类型,它再次假定 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 来避免每个处理行 transformation/casting,并使事情更有条理。
我就是无法释怀...
抱歉 lack-lustre 标题,但很难描述...
假设我有两个 table(cad 和 cad_polygon)...
cad 和 cad_polygon 共享与 one-another (cad_pid)...
相关的同一列cad 有这些列:cad_pid、jrsdctn_id
而 cad_polygon 有这些列:cad_pid、ogc_fid、wkb_geometry
现在,我正在处理的以下查询(尝试了半天)根据经纬度 co-ord 的度数选择一个地块,从那个明显更小的多边形子集中,它找到它们的距离(以米为单位)从给定的 long,lat co-ord,然后仅显示质心在 long,lat co-ord.
500 米以内的多边形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;
我想添加到这个并使用这个查询吐出的列表,加入我的另一个 table (cad) 这样我就可以为每个结果行提供额外的列 "jrsdctn_id".. . 即:
示例数据为: 加元:
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
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;
有点晚了,接受的答案关于 JOIN
当然是绝对正确的,但这实际上与 GIS 有很大关系,它的意识最终使事情对你来说更容易:
您似乎正在使用自定义 CRS 或 ogr2ogr(或任何 GDAL/OGR 函数)在 PostGIS 中未找到匹配的 SRID/projection spatial_ref_sys table;但是,任何使用 LonLat 作为 spherical/shperoidal 代数输入的 PostGIS 函数都将始终假定您的坐标在 EPSG:4326 (WGS84).
中如果您的 LonLat 与 WGS84 的 不完全 匹配,结果将会关闭!
现在,PostGIS 也有 geography 类型,它再次假定 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 来避免每个处理行 transformation/casting,并使事情更有条理。
我就是无法释怀...