Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MSSQL 2008R2避免类似矩阵表中的重复项_Sql_Sql Server_Arrays_Matrix - Fatal编程技术网

MSSQL 2008R2避免类似矩阵表中的重复项

MSSQL 2008R2避免类似矩阵表中的重复项,sql,sql-server,arrays,matrix,Sql,Sql Server,Arrays,Matrix,我试图找到解决办法,但当记录低于某个数字时,解决起来很容易。但是 我有一份有81590张唱片的原始名单 Id Loc Sales LatLong 1 a 100 ... 2 b 110 ... 3 c 105 ... 4 d 125 ... 5 e 123 ... 6 f 35 ... . . . 81,590 ... ... ... 我需要将列表中的所有项目相互比较 Id L1 L2 Dist 1 a

我试图找到解决办法,但当记录低于某个数字时,解决起来很容易。但是

我有一份有81590张唱片的原始名单

Id  Loc Sales   LatLong
1   a   100 ...
2   b   110 ...
3   c   105 ...
4   d   125 ...
5   e   123 ...
6   f   35  ...
.
.
.
81,590  ... ... ...
我需要将列表中的所有项目相互比较

    Id  L1  L2  Dist    
    1   a   a   0   --> Not needed. Self comparison.
    2   a   b   26  
    3   a   c   150 --> Not needed. Distance >100.
    4   a   d   58  
    5   b   a   26  --> Not needed. Repeated record.
    6   b   b   0   --> Not needed. Self comparison.
    7   b   c   15  
    8   b   d   151 --> Not needed. Distance >100.
    9   c   a   150 --> Not needed. Repeated record.
    10  c   b   15  --> Not needed. Repeated record.
    11  c   c   0   --> Not needed. Self comparison.
    12  c   d   75  
    13  d   a   58  --> Not needed. Repeated record.
    14  d   b   151 --> Not needed. Repeated record.
    15  d   c   75  --> Not needed. Repeated record.
    16  d   d   0   --> Not needed. Self comparison.
但正如上面记录旁边所示,最终结果需要是一个列表,其中:

1仅当记录位于一定距离(例如100英里)时,才会将它们相互比较

这是非常低效的,我会用60亿条记录构建一个表,然后删除一半,等等

是否有一种方法能够以更高效、更少步骤、更少选择/删除/更新的方式到达最终产品

将最终数据集插入目标所需的select语句是什么


对我来说,这听起来像是一个表与它自身的连接,以及一个按键的迭代进行过滤,但这就是我被卡住的地方。

您使用什么算法来计算两点之间的距离?简单的“世界是平的”笛卡尔数学,还是那个充满三角学的“单词是扁球体”的?这可能会导致严重的CPU需求

最好生成一个“距离此位置X以内的位置”表,并将其永久存储;除非发生地震这样的重大事件,否则情况不会改变

就查询而言,基本联接很简单:

SELECT
   t1.Loc L1
  ,t2.Loc L2
 from MyTable t1
  inner join MyTable t2
   on t2.Loc > t1.Loc
如果在一个名为“distanceFunction”的函数中有距离公式,它可能看起来像:

WITH cteCalc as (
    select
       t1.Loc L1
      ,t2.Loc L2
      ,dbo.distanceFunction(t1.LatLong, t2.LatLong) Dist
     from MyTable t1
      inner join MyTable t2
       on t2.Loc > t1.Loc
     where dbo.distanceFunction(t1.LatLong, t2.LatLong) < @MaxDistance)
 INSERT TargetTable (L1, L2, Dist)
 SELECT
    L1
   ,L2
   ,Dist
  where Dist <= @MaxDistance
当然,这可能会破坏您的系统,这仅仅是因为在向目标表写入数十亿行时,事务日志会变得太大。我建议构建一个循环,依次处理每个位置,最终查询如下:

WITH cteCalc as (
    select
       t1.Loc L1
      ,t2.Loc L2
      ,dbo.distanceFunction(t1.LatLong, t2.LatLong) Dist
     from MyTable t1
      inner join MyTable t2
       on t2.Loc > t1.Loc
     where dbo.distanceFunction(t1.LatLong, t2.LatLong) < @MaxDistance
      and t1.Loc = @ThisIterationLoc)
 INSERT TargetTable (L1, L2, Dist)
 SELECT
    L1
   ,L2
   ,Dist
  where Dist <= @MaxDistance

第一次传递返回81589,以距离太远的为准,第二次传递返回81588,以此类推。

以下是我将如何解决此问题的概述:

把索引放在经纬度上 对距离的范围框计算距离的lat和long。然后你知道你的距离,不是一个圆,而是包含在这个三角形中。你也知道它不在这个三角洲之外。这大大限制了问题的解决

例如,如果距离的lat和long变化为10,则框中100100处的位置将由lat和long的95、95和105105值定义

编写一个查询,从最低id查看每个元素,并搜索id更大的其他元素,以避免在lat和log的增量中重复,并将其保存到临时表中。 迭代该表并进行完整计算,看看它是否在圆内而不是距离框内。
沃特?你有数据,需要根据距离来比较,但是你怎么知道什么时候可以匹配呢?它完全是基于距离的吗?我担心你的问题匿名化,你掩盖了有用的信息,这完全取决于距离。我正在使用经济普查数据,希望将当地的销售水平与100岁以下的其他地区进行比较。哥伦比亚大学花了10英镑。StL花费1000英镑,彼此相距超过100英里。预期输出将显示什么?堪萨斯城->哥伦比亚30:10,KC->StL 30:1000或KC->哥伦比亚,KC->StL,哥伦比亚->StL。换句话说,您是在为整个域生成结果,还是从一个中心点查找所有位置?还有,您的表结构是什么样的?SQL Server 2005、2008、2012、2014?评论不错,@billinkc。作为解释的一部分,我添加了更多的细节和几个示例。如果没有额外的数据或巧妙的技巧,您将不得不将每一行与每一行进行匹配,并计算距离。大笑。
WITH cteCalc as (
    select
       t1.Loc L1
      ,t2.Loc L2
      ,dbo.distanceFunction(t1.LatLong, t2.LatLong) Dist
     from MyTable t1
      inner join MyTable t2
       on t2.Loc > t1.Loc
     where dbo.distanceFunction(t1.LatLong, t2.LatLong) < @MaxDistance
      and t1.Loc = @ThisIterationLoc)
 INSERT TargetTable (L1, L2, Dist)
 SELECT
    L1
   ,L2
   ,Dist
  where Dist <= @MaxDistance