В Oracle Spatial у меня есть две таблицы ( AVALREGULACAO и ATROCOADUTOR ), представляющие точки и линии соответственно.
Структура обеих таблиц следующая:
AVALREGULACAO ( 295 точечных записей )
IPID [число (10)]
ГЕОМЕТРИЯ [MDSYS.SDO_GEOMETRY]
ATROCOADUTOR ( 12536 записей строк)
IPID [число (10)]
ГЕОМЕТРИЯ [MDSYS.SDO_GEOMETRY]
Мне нужно найти ближайшего соседа ATROCOADUTOR от каждого AVALREGULACAO и вычислить расстояние между ними
AVALREGULACAO_IPID |ATROCOADUTOR _IPID |РАССТОЯНИЕ
Я использовал 2 варианта
1
SELECT /*+ ORDERED */ A.IPID, B.IPID, MIN(SDO_GEOM.SDO_DISTANCE(sdo_cs.make_2d(A.GEOMETRY), sdo_cs.make_2d(B.GEOMETRY), 0.005)) as DISTANCE
FROM AVALREGULACAO A, ATROCOADUTOR B
GROUP BY c_b.IPID,c_d.IPID;
Это занимает довольно много времени для вычисления - генерируетогромный выход 295 x 12536 = 3 698 120 возможных комбинаций (декартово произведение).Кроме того, выходной файл CSV не может вместить все эти записи (ограничение 1 048 576 строк)
Мне нужно только 295 записей, соответствующих 295 AVALREGULACAO.
2
Я также пробовал / адаптировал другой запрос с оператором ближайшего соседа (nn)
PROMPT IPID, nearest_IPID, distance
select /*+ ORDERED USE_NL(s,s2)*/
s.IPID,
s2.IPID as nearest_IPID,
TO_CHAR(REPLACE(mdsys.sdo_geom.sdo_distance(sdo_cs.make_2d(s.GEOMETRY),sdo_cs.make_2d(s2.GEOMETRY),0.05), ',','.')) as distance
from AVALREGULACAO s,
ATROCOADUTOR s2
where s2.IPID in (select IPID
from AVALREGULACAO s3
where sdo_nn(s3.GEOMETRY,s.GEOMETRY,'sdo_batch_size=10',1) = 'TRUE'
and s3.IPID <> s.IPID
and rownum < 2)
order by 1,2;
Этот запрос занимает вечность - мне нужно остановить процесс до его завершения.
Я думаюМне не хватает того, как оптимизировать / отфильтровать желаемые результаты.
Буду признателен за любые советы по эффективному решению этой проблемы.
Заранее спасибо, Педро
PS: @Boneist.Большое спасибо за ввод.
К сожалению, я получил ошибку после применения вашего запроса (все еще пытаюсь работать с семантикой / синтаксисом новых команд KEEP, dens_rank)
SELECT a.ipid a_ipid,
MIN(b.ipid) KEEP (dense_rank FIRST order by sdo_nn(a.GEOMETRY,b.GEOMETRY,'sdo_batch_size=10',1)) b_ipid,
MIN(sdo_geom.sdo_distance(sdo_cs.make_2d(a.geometry), sdo_cs.make_2d(b.geometry), 0.005)) AS distance
FROM avalregulacao a
INNER JOIN atrocoadutor b ON sdo_nn(a.GEOMETRY,b.GEOMETRY,'sdo_batch_size=10',1) = 'TRUE'
GROUP BY a.ipid;
Ошибка
Error starting at line : 1 in command -
SELECT a.ipid a_ipid,
MIN(b.ipid) KEEP (dense_rank FIRST order by sdo_nn(a.GEOMETRY,b.GEOMETRY,'sdo_batch_size=10',1)) b_ipid,
MIN(sdo_geom.sdo_distance(sdo_cs.make_2d(a.geometry), sdo_cs.make_2d(b.geometry), 0.005)) AS distance
FROM avalregulacao a
INNER JOIN atrocoadutor b ON sdo_nn(a.GEOMETRY,b.GEOMETRY,'sdo_batch_size=10',1) = 'TRUE'
GROUP BY a.ipid
Error at Command Line : 2 Column : 45
Error report -
SQL Error: ORA-29907: foram encontradas etiquetas em duplicado em invocações primárias
29907. 00000 - "found duplicate labels in primary invocations"
*Cause: There are multiple primary invocations of operators with
the same number as the label.
*Action: Use distinct labels in primary invocations.