在oracle空间中,我有两个表( AVALREGULACAO 和 ATROCOADUTOR ),分别代表点和线。
两个表的结构如下:
AVALREGULACAO( 295点记录)
IPID [number(10)]
几何[MDSYS.SDO_GEOMETRY]
ATROCOADUTOR( 12536行记录)
IPID [number(10)]
几何[MDSYS.SDO_GEOMETRY]
我需要从每个AVALREGULACAO中找到最近的ATROCOADUTOR邻居,并计算它们之间的距离
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 = 3698120可能的组合(笛卡尔积)的巨大输出。此外,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,deny_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.
答案 0 :(得分:0)
我认为您可能正在追求类似的东西:
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;
这将两个表连接到最近的neighbor函数,这将减少返回的行数。
MIN(b.ipid) KEEP (dense_rank first order by sdo_nn(a.GEOMETRY,b.GEOMETRY,'sdo_batch_size=10',1))
只是返回最低的b.ipid值以获得最小的差异。
(我认为此查询将按原样运行,但我无法对其进行测试。您可能必须进行连接并将sdo_nn(a.GEOMETRY,b.GEOMETRY,'sdo_batch_size=10',1)
作为子查询中的列,然后在外部进行分组查询。)