查询"对"在大桌子里

时间:2017-01-26 11:50:26

标签: sql sql-server

已更新

我在SQL Server 2014中有一个大表,我需要找到"对"对应于关键字段中每个值之间所需的接近度。在现实生活中,它通过给定的接近度搜索所有位置,而没有搜索区域的中心。 keyfield的数据类型为Geography,并在地图上填充了坐标点。

create table data
(
   id        int, 
   keyfield  geography
);

id    keyfield
-------------- 
1          a,b 
2          g,h
3          c,d
4          k,l
5          x,z

当搜索距离小于N的位置对时,预期结果将是

id1   id2
------------- 
1     3      <- distance between 1 and 3 is less than N
2     4      <- distance between 2 and 4 is less than N

到目前为止(感谢评论&#34;重复&#34;)我有

select t1.id, t2.id,  
from data t1, data t2  
where t1.keyfield.STDistance(t2.keyfield) < N
and t1.id < t2.id

create table search
(
   id1 int,
   id2 int 
);
--------------

declare @id int  
declare @g geography

declare c cursor for  
select id, keyfield from data

open c   
fetch next from c into @id, @g   

while @@fetch_status = 0   
begin   
       insert into search
       select @id, id from data
       where keyfield.STDistance(@g) < N
       and @id < id

       fetch next from c into @id, @g
end   

close c   
deallocate c

即使在拥有10-20K记录的小型套装上,这两种方法都无法接​​受。

同样,它不是从中心点(y,z)搜索N半径内的位置,而是搜索彼此之间距离为N的所有位置。

3 个答案:

答案 0 :(得分:0)

假设你的“距离”函数是对称的,那么:

select t1.id, t2.id
from table1 t1 cross join
     table2 t2
     on t1.id < t2.id and myfunction(t1.keyfield, t2.keyfield) < 50;

这对于大型桌子来说会很昂贵,所以它可能无法解决您的实际问题。

我建议您提出另一个问题,提供有关字段外观的更多信息和示例以及“距离”函数的逻辑。

答案 1 :(得分:0)

 select t1.id, t2.id
 from table1 t1
 join table1 t2
   ON t2.id between t1.keyfield - 50 and t1.keyfield + 50
  AND t1.id < t2.id

答案 2 :(得分:0)

您可以在JOIN条件中指定差异,如下所示:

CREATE TABLE #Table1
    ([id] int, [keyfield] int)
;

INSERT INTO #Table1
    ([id], [keyfield])
VALUES
    (1, 100),
    (2, 200),
    (3, 130),
    (4, 201),
    (5, 999);

SELECT t1.id ,
       t1.keyfield ,
       t2.id,
       t2.keyfield
FROM #Table1 t1
INNER JOIN #Table1 t2 ON t2.keyfield <= t1.keyfield + 50 AND t2.keyfield > t1.keyfield

DROP TABLE #Table1

<强> Ouptut:

id  keyfield    id  keyfield
1   100         3   130
2   200         4   201

这并没有考虑到您的功能,因为您没有指定它的作用。因此,我删除了WHERE子句,这可能会为您提供另一种方法。