У меня есть table A
с Id
и Geometry
И Temporary table B
Каждая геометрия Temporary table B
имеет пересекающуюся геометрию в Table A
. Я хочу найти пересекающуюся геометрию и объединить геометрию. Итоговая таблица должна иметь идентификатор Table A
, который имеет пересечение и объединение геометрии. Если есть более 1 пересекающейся геометрии, выберите любую.
Я не могу выполнить соединение здесь, так как между этими таблицами нет общего столбца, поэтому не знаю, как получить окончательный результат.
Если набор данных не такой большой, а значения геометрии следуют тому же шаблону, как показано выше, вы можете посмотреть на это решение.
WITH a AS (
SELECT 1 AS id
, 'LineAB' AS geometry
UNION ALL
SELECT 2
, 'LineDE'
UNION ALL
SELECT 3
, 'LineFG'
UNION ALL
SELECT 4
, 'LineXY' )
, temp_b AS (
SELECT 'LineBC' AS geometry
UNION ALL
SELECT 'LineCD'
UNION ALL
SELECT 'LineEF' )
, a_last AS (
SELECT a.id
, a.geometry
, RIGHT(a.geometry, 1) AS a_key -- get the last symbol for further join with temp_b
FROM a )
, a_nlast AS (
SELECT a.id
, a.geometry
, SUBSTRING(a.geometry, 5, 1) AS a_key
FROM a )
, b_nlast AS (
SELECT temp_b.geometry
, SUBSTRING(temp_b.geometry, 5, 1) AS b_key -- get one symbol before the last symbol for further join with a table
FROM temp_b )
, b_last AS (
SELECT temp_b.geometry
, RIGHT(temp_b.geometry, 1) AS b_key
FROM temp_b )
-- try all possible combinations of last and not last sybols from both tables
SELECT a_last.id
, CONCAT('Union (', SUBSTRING(a_last.geometry, 5, 2), '+', SUBSTRING(b_nlast.geometry, 5, 2), ')')
FROM a_last JOIN b_nlast ON a_last.a_key = b_nlast.b_key
UNION ALL
SELECT a_last.id
, CONCAT('Union (', SUBSTRING(a_last.geometry, 5, 2), '+', SUBSTRING(b_last.geometry, 5, 2), ')')
FROM a_last JOIN b_last ON a_last.a_key = b_last.b_key
UNION ALL
SELECT a_nlast.id
, CONCAT('Union (', SUBSTRING(a_nlast.geometry, 5, 2), '+', SUBSTRING(b_last.geometry, 5, 2), ')')
FROM a_nlast JOIN b_last ON a_nlast.a_key = b_last.b_key
UNION ALL
SELECT a_nlast.id
, CONCAT('Union (', SUBSTRING(a_nlast.geometry, 5, 2), '+', SUBSTRING(b_nlast.geometry, 5, 2), ')')
FROM a_nlast JOIN b_nlast ON a_nlast.a_key = b_nlast.b_key;
Это решение берет определенные символы из заданного шаблона и пробует разные комбинации, чтобы сформировать список всех возможных комбинаций.
Вопрос по идентификаторам. Говорят, что он должен брать id из таблицы, но если вы хотите, чтобы он был уникальным, лучше создать отдельную таблицу, куда можно было бы складывать полученные комбинации со своими уникальными id.
В демо я взял типы intrange
для имитации типов geometry
. Диапазоны достаточно близки, чтобы получить один и тот же запрос:
SELECT DISTINCT ON (b.id) -- 3
a.id,
a.geom + b.geom -- 2
FROM a
JOIN b ON a.geom && b.geom -- 1
&&
, в вашем случае должен быть st_intersects(a.geom, b.geom)
+
, в вашем случае должно быть st_union(a.geom, b.geom)
DISTINCT ON(b.id)
гарантирует, что на каждый b.id
будет только одна записьИтак, ваш окончательный запрос должен выглядеть так:
SELECT DISTINCT ON (b.id) -- 3
a.id,
st_union(a.geom, b.geom) -- 2
FROM a
JOIN b ON st_intersects(a.geom, b.geom) -- 1
Ты прав. Он должен быть DISTINCT ON (b.id)
@ S-Man, но у b нет идентификатора столбца.
У вас всегда должен быть идентификатор в вашей таблице! Однако вы можете легко сгенерировать его, используя оконную функцию row_number(): dbfiddle.uk/…
@ S-Man, это хороший момент. К сожалению, когда я использую row_number в сочетании с st_dump, он генерирует один и тот же идентификатор для всех. SELECT row_number() OVER () as id,(st_dump(ST_GeomFromText('MULTILINESTRING((-29-27,-30-29.7,-36-31,-45-33),(-45-33,-46-32 )))'))).геом
Вы можете сделать это в подзапросе: dbfiddle.uk/…
Спасибо, что приняли. Буду признателен, если вы тоже проголосуете. Пожалуйста, не забудьте проголосовать за ВСЕ ответы, которые могут каким-либо образом помочь. Это чтит время и усилия, вложенные ответчиком в вашу проблему.
Я полагаю, что следующий SQL будет работать:
SELECT a.id, ST_UNION(a.geometry, b.geometry)
FROM table_A as a, temp_table_B as b
WHERE ST_INTERSECTS(a.geometry, b.geometry)
Вы можете сгруппировать результаты для обработки нескольких пересечений.
Не соответствует последнему требованию. Он возвращает два союза, если они есть.
ОП не ясно, как обрабатывать несколько пересечений. Что делать, если геометрия из table_A пересекается с несколькими геометриями из temp_table_B? OP только указывает, что произойдет в противоположном случае (если геометрия из temp_table_B пересекается с несколькими геометриями из table_A, сохраните один идентификатор из table_A). Поэтому я разместил основную логику, ОП может редактировать ее в соответствии со своими потребностями.
По тому, что спрашивает OP, значения a.id не обязательно различны. OP говорит, что если геометрия из temp_table_B пересекается с геометрией из table_A, следует сохранить один идентификатор a.id. Но что, если геометрия из table_A пересекается с несколькими геометриями из temp_table_B?