MSSQL 2008R2避免类似矩阵表中的重复项
我试图找到解决办法,但当记录低于某个数字时,解决起来很容易。但是 我有一份有81590张唱片的原始名单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
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