Я использую Postgresql 9,6
У меня есть таблица со строками данных.Давайте назовем это TABLE1.ТАБЛИЦА 1 имеет столбец pkid (серийный первичный ключ).
Фактически каждая строка является зданием, и операция группировки основана на том, касаются ли здания друг друга или нет (БД с расширением PostGIS).Теперь моя проблема не в том, чтобы определить, когда два здания касаются другого, а в том, чтобы записать пары во временную таблицу.
Я извлекаю их подмножество, используя подзапрос SELECT (давайте назовем его subquery1), иМне нужно сгруппировать их по определенным критериям.Подзапрос1 возвращает набор строк с двумя столбцами, pkid_bat1 и pkid_bat2, pkid 2 разных строк TABLE1, которые связаны вместе (на основе JOIN, использующего функцию PostGIS).
Я возьму примерЧтобы прояснить ситуацию:
Допустим, у меня есть 3 здания, которые касаются друг друга: A, B и C. Подзапрос1 вернет 6 строк в виде пар pkid: AB, BA, AC, CA, BC, CB.
Чтобы записать, что эти 3 здания связаны друг с другом, мне фактически нужны только 2 пары, такие как: AB и AC.
Итак, что я сделал до сих пор: после подзапроса1 у меня естьвложил другой подзапрос SELECT (подзапрос2), который для каждой из 6 строк возвращает в качестве первого столбца минимум двух pkid и в качестве 2-го столбца максимум двух pkid, и добавил предложение DISTINCT.Таким образом, 6 рядов AB, BA, AC, CA, BC, CB становятся 3 рядами: AB, AC, BC.
Мне все еще нужно избавиться от ряда BC.
Послеподзапрос2, у меня есть еще один вложенный подзапрос (подзапрос3), который самостоятельно объединяет результаты подзапроса2:
SELECT mpb1.pkid_bat1 , mpb1.pkid_bat2
FROM resultsSubQuery2 AS mpb1
LEFT JOIN resultsSubQuery2 AS mpb2
ON mpb1.pkid_bat1 = mpb2.pkid_bat2
WHERE mpb2.pkid_bat2 IS NULL
Это работает: из строк AB, AC и BC он будет содержать только AB иAC, потому что A никогда не находится среди pkid_bat2 (благодаря использованию функций min и max в подзапросе2).Но это занимает слишком много времени.
Есть ли другой способ решения этой проблемы (создание наборов pkid)?
Редактировать: Весьв коде есть небольшое изменение в подзапросе 2, чтобы заменить использование DISTINCT + min и max более простым использованием «<» в предложении WHERE: </p>
WITH isolatedPonctualBuildings AS
(
SELECT DISTINCT ON (bat.pkid)
bat.pkid, bat.pkid_emprise, bat.origine , bat.origine_id, bat.geom
FROM Temp_batiments_sites AS bat
LEFT JOIN Temp_recoupements_bâtiments AS recoup
ON bat.pkid = recoup.pkid_batiment2
WHERE bat.type_geometry = 'Point'
AND recoup.pkid IS NULL
),
matchedPonctualBuildings AS
(
SELECT
bat1.pkid AS pkid_bat1,
bat2.pkid AS pkid_bat2
FROM isolatedPonctualBuildings AS bat1
JOIN isolatedPonctualBuildings AS bat2
ON bat1.pkid_emprise = bat2.pkid_emprise
AND ST_Intersects (bat1.geom , bat2.geom)
AND ( bat1.origine != bat2.origine OR bat1.origine_id != bat2.origine_id )
WHERE bat1.pkid < bat2.pkid
)
SELECT
mpb1.pkid_bat1 , mpb1.pkid_bat2
FROM matchedPonctualBuildings AS mpb1
LEFT JOIN matchedPonctualBuildings AS mpb2
ON mpb1.pkid_bat1 = mpb2.pkid_bat2
WHERE mpb2.pkid_bat2 IS NULL