问题:我需要选择,对于我的表中每个建筑物,其中至少有2个药房和1个半径范围内的2个教育中心,所有POI(药房,商业中心,医疗中心,教育中心,警察局) ,消防局)距离相应建筑物1公里范围内。表结构 - >
building(id serial,name varchar)
poi_category(id serial,cname varchar)--cname是课程的类别名称
poi(id serial,name varchar,c_id integer) - c_id是FK引用poi_category(id)
所有坐标列都是几何类型而不是地理位置(让我们称之为geom)
这是我认为应该这样做的方式,但我不确定它是否正确,更不用说这个问题的最佳解决方案
SELECT r.id_b, r.id_p
FROM (
SELECT b.id AS id_b, p.id AS id_p, pc.id AS id_pc,pc.cname
FROM building AS b, poi AS p, poi_category AS pc
WHERE ST_DWithin(b.geom,p.geom, 1000) AND p.c_id=pc.id
) AS r,
(
SELECT * FROM r GROUP BY id_b
) AS r1
HAVING count (
SELECT *
FROM r, r1
WHERE r1.id_b=r.id_b AND r.id_pc='pharmacy'
)>1
AND
count (
SELECT *
FROM r, r1
WHERE r1.id_b=r.id_b AND r.id_pc='ed. centre'
)>1
这是我需要的方式吗?从性能的角度来看,哪种解决方案会更好?最优雅的解决方案呢? 我也在这里发布:http://gis.stackexchange.com/questions/11445/postgis-advanced-selection-query
答案 0 :(得分:3)
这是我详细阐述的解决方案。这是我能找到的最快的,但它仍然很慢。鉴于任务的性质,我怀疑它可以更快...
WITH
building AS (
SELECT way, osm_id
FROM osm_polygon
WHERE tags @> hstore('building','yes')
--ORDER BY 1
LIMIT 1000
),
pharmacy AS (
SELECT way
FROM osm_poi
WHERE tags @> hstore('amenity','pharmacy')
),
school AS (
SELECT way
FROM osm_poi
WHERE tags @> hstore('amenity','school')
)
SELECT ST_AsText(building.way) AS geom, building.osm_id AS label
FROM building
WHERE
(SELECT count(*) > 1
FROM pharmacy
WHERE ST_DWithin(building.way,pharmacy.way,1000))
AND
(SELECT count(*) > 1
FROM school
WHERE ST_DWithin(building.way,school.way,1000))
你的。 S上。