Это вполне выполнимо прямо из PostgreSQL
с PostGIS
.
Учитывая вашу структуру таблицы ...
CREATE TEMPORARY TABLE t (name TEXT, type TEXT, geom GEOGRAPHY);
... и ваши тестовые данные ...
INSERT INTO t VALUES ('House1','Big', ST_MakePoint(1,2));
INSERT INTO t VALUES ('House11','Bigger', ST_MakePoint(2,2));
INSERT INTO t VALUES ('House12','Biggest', ST_MakePoint(3,2));
INSERT INTO t VALUES ('House13','Small', ST_MakePoint(4,2));
INSERT INTO t VALUES ('House14','Medium', ST_MakePoint(5,2));
(Примечание: здесь не имеет смысла разделять lat, long на разные столбцы. PostGIS может хранить оба в одном GEOGRAPHY
или GEOMETRY
столбце. См. ST_MakePoint
для более подробной информации.)
"Найдите все дома типа Большой, в которых есть Малый и Средний дом
его радиус 10 км "
Попробуйте что-то подобное, используя ST_Distance
:
WITH j AS (SELECT * FROM t WHERE type = 'Big')
SELECT
j.name,j.type,
ST_Distance(j.geom,t.geom) AS distance,
t.name, t.type
FROM j,t
WHERE
ST_Distance(j.geom,t.geom) > 10000 AND
t.type IN ('Small','Medium');
name | type | distance | name | type
--------+------+-----------------+---------+--------
House1 | Big | 333756.3481116 | House13 | Small
House1 | Big | 445008.41595616 | House14 | Medium
(2 Zeilen)
(Этот запрос возвращает записи, которые находятся на расстоянии более 10 тысяч метров от дома типа Big
. Просто адаптируйте первый оператор where для своих нужд)
РЕДАКТИРОВАТЬ: Запрос на основе комментариев.
WITH j AS (SELECT *, ARRAY(SELECT DISTINCT t2.type
FROM t t2
WHERE t2.type IN ('Small','Medium') AND
ST_Distance(t2.geom,t1.geom) < 100000
) AS nearHouseType
FROM t t1 WHERE type = 'Big')
SELECT *
FROM j
WHERE j.nearHouseType @> '{Medium, Small}'::TEXT[]