2012-08-01 80 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