Как выполнить запрос к двум несвязанным таблицам

У меня есть table A с Id и Geometry

И Temporary table B

Каждая геометрия Temporary table B имеет пересекающуюся геометрию в Table A. Я хочу найти пересекающуюся геометрию и объединить геометрию. Итоговая таблица должна иметь идентификатор Table A, который имеет пересечение и объединение геометрии. Если есть более 1 пересекающейся геометрии, выберите любую.

Я не могу выполнить соединение здесь, так как между этими таблицами нет общего столбца, поэтому не знаю, как получить окончательный результат.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
0
253
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Если набор данных не такой большой, а значения геометрии следуют тому же шаблону, как показано выше, вы можете посмотреть на это решение.

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
  1. Условием соединения должна быть проверка на пересечение. Для диапазонов это оператор &&, в вашем случае должен быть st_intersects(a.geom, b.geom)
  2. Объедините обе геометрии. Здесь это делается с помощью оператора +, в вашем случае должно быть st_union(a.geom, b.geom)
  3. 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

По тому, что спрашивает OP, значения a.id не обязательно различны. OP говорит, что если геометрия из temp_table_B пересекается с геометрией из table_A, следует сохранить один идентификатор a.id. Но что, если геометрия из table_A пересекается с несколькими геометриями из temp_table_B?

treecon 15.12.2020 11:00

Ты прав. Он должен быть DISTINCT ON (b.id)

S-Man 15.12.2020 11:02

@ S-Man, но у b нет идентификатора столбца.

user1298426 15.12.2020 11:28

У вас всегда должен быть идентификатор в вашей таблице! Однако вы можете легко сгенерировать его, используя оконную функцию row_number(): dbfiddle.uk/…

S-Man 15.12.2020 11:39

@ 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 )))'))).геом

user1298426 15.12.2020 11:46

Вы можете сделать это в подзапросе: dbfiddle.uk/…

S-Man 15.12.2020 11:57

Спасибо, что приняли. Буду признателен, если вы тоже проголосуете. Пожалуйста, не забудьте проголосовать за ВСЕ ответы, которые могут каким-либо образом помочь. Это чтит время и усилия, вложенные ответчиком в вашу проблему.

S-Man 15.12.2020 13:56

Я полагаю, что следующий 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) 

Вы можете сгруппировать результаты для обработки нескольких пересечений.

Не соответствует последнему требованию. Он возвращает два союза, если они есть.

S-Man 15.12.2020 09:01

ОП не ясно, как обрабатывать несколько пересечений. Что делать, если геометрия из table_A пересекается с несколькими геометриями из temp_table_B? OP только указывает, что произойдет в противоположном случае (если геометрия из temp_table_B пересекается с несколькими геометриями из table_A, сохраните один идентификатор из table_A). Поэтому я разместил основную логику, ОП может редактировать ее в соответствии со своими потребностями.

treecon 15.12.2020 10:51

Другие вопросы по теме