2012-08-01 66 views
4

我有一组30000个单位的表,其中每个单位的位置由坐标(X,Y)定义。我想知道哪些单位距离每个单元都有一定的距离?SQL:使用数学运算匹配表

Ex。

UnitiID X Y 
A   10 15 
B   10 25 
C   25 15 


proc sql; 
    create table work.Test2 as 
    select distinct 
    a.UnitID, 
    a.X, 
    a.Y, 
    b.UnitID as CloseUnit label="CloseUnit", 
    sqrt((a.X-b.X)**2 + (a.Y-b.Y)**2) as distance 
    from 
    work.Test as a 
    left join 
    work.Test as b 
    on 
    0<sqrt((a.X-b.X)**2 + (a.Y-b.Y)**2) <=15 
    ; 
quit; 

结果:

UnitiID X Y CloseUnit Distance 
A   10 15 B   10 
A   10 15 C   15 
B   10 25 A   10 
C   25 15 A   15 

这需要整个表了大量的CPU时间,因为我们会做300'000^2的比较,我怎么可能瓶坯这个任务?

+1

几个DBMS具有空间特征。你在做什么? (SQL-Server,Postgres,Oracle,...?) – 2012-08-01 14:09:46

+0

您可以在边界框((x + - r),(y + - d))上重新添加一个额外的位置,这将削减大量的比较。可以是'ABS(a.x-b.x)<= r AND ABS(a.y-b.y)<= r' @ypercube:SAS具有SQL语言的(有限)实现。 – wildplasser 2012-08-01 14:11:39

+1

您可以通过平方双方(即删除sqrt并使用225代替15)来跳过sqrt。 – dasblinkenlight 2012-08-01 14:13:56

回答

3

想到几个优化。首先,您可以检查X轴和Y轴的距离。如果任一个大于15,则该点不能在范围内。一个子查询会指示数据库做较快检查第一:完成时

where (aX-bX)**2 + (aY-bY)**2 <= 15**2 

磨边比生根快,尤其是:

select * 
from (
     select a.X as aX 
     ,  b.X as bX 
     ,  a.Y as aY 
     ,  b.Y as bY 
     from Test a 
     join Test b 
     on  abs(a.X - b.X) <= 15 
       and abs(a.Y - b.Y) <= 15 
     ) as SubQueryAlias 
where sqrt((aX-bX)**2 + (aY-bY)**2) <= 15 

第二个优化将是移动sqrt计算向右上一个常数。

要进一步优化,请查看Wikipedia article on Geohashing

+0

我需要通过(aX-bX)** 2 +(aY-bY)** 2来计算距离,并且根据ax bx ay显示距离点的方式如何进行查询 – 2012-12-06 06:47:23