【问题标题】:Distances between multiple geography values多个地理值之间的距离
【发布时间】:2014-07-09 08:39:50
【问题描述】:

我们使用多个地理点的平均值来获取平均值并将其指定为项目位置。 我现在需要追踪这些数据,并以某种方式识别与其他点相距太远的任何原始点。 我认为我需要使用 STDistance,但担心要正确使用,我需要 2 个游标来循环遍历并将每个点与其他点进行比较。

如果有一个示例有助于澄清:我们需要锁定物品的 GPS 坐标,因此我们要求用户在他们处于物品的大致区域时按下按钮,并记录 GPS 坐标。然后我们取其中的 5 个并将项目的位置设置为 AVG(Location.Lat) + AVG(Location.Long)。 当其中一个用户在几英里外完成按下时,就会出现问题,将平均值抛出,因此现在需要识别其中的任何一个。

关于仅在 SQL 中执行此操作的正确/有效方法的任何想法? (处理数以百万计的条目,因此担心每个条目循环 2 个游标会削弱数据库)

【问题讨论】:

  • 我认为 SQL2008 不支持空间函数。此外,创建空间索引对查询速度也有很大帮助。

标签: sql-server-2008 tsql sqlgeography


【解决方案1】:

丢弃统计上不重要的数据对人类来说很容易,但对计算机来说可能有点麻烦。在您的情况下尤其如此,因为您处理的是二维(纬度和经度)。

我建议你看看我几年前写的这篇博客:Calculating Mean Median and Mode With SQL Server

对于纬度和经度,小数点后的每个数字代表一个距离。您可以做的是将纬度和经度四舍五入到一定的小数位,找到模式。去掉与众数不一样的点,然后对剩余的未取整项进行平均。

由于您在二维中工作,因此您需要分别对纬度和经度值执行此操作,因为纬度可能会偏离而经度不是(这将代表一个不好的点,即北或南实际位置)。同样,经度可能会偏离,而纬度显然还可以。如果任何一个值都是“坏的”,那么你应该完全放弃这一点。

这是我所说的一个例子:

Declare @Temp Table(Lat Decimal(9,6), Lon Decimal(9,6))

Insert Into @Temp Values(20.12341, 10.98731)
Insert Into @Temp Values(20.12342, 10.98732)
Insert Into @Temp Values(20.12343, 10.98733)
Insert Into @Temp Values(20.12344, 10.98734)
Insert Into @Temp Values(20.12344, 10.68734) -- Latitude OK, Longitude bad
Insert Into @Temp Values(20.32344, 10.98734) -- Longitude OK, Latitude bad
Insert Into @Temp Values(20.42340, 10.68730) -- Both are bad

Select  Avg(Lat), Avg(Lon)
From    @Temp

Select  Avg(T.Lat) As Latitude,
        Avg(T.Lon) As Longitude
From    @Temp T
        Inner Join (
            -- Calculate the mode for the latitude
            Select  Top 1 Convert(Decimal(9,4), Lat) As ModeOfLat
            From    @Temp
            Group By Convert(Decimal(9,4), Lat)
            Order By Count(*) DESC
            ) As Latitudes
            On Convert(Decimal(9,4), Lat) = Latitudes.ModeOfLat
        Inner Join (
            -- Calculate the mode for the longitude
            Select  Top 1 Convert(Decimal(9,4), Lon) As ModeOfLon
            From    @Temp
            Group By Convert(Decimal(9,4), Lon)
            Order By Count(*) DESC
            ) As Longitudes
            On Convert(Decimal(9,4), Lon) = Longitudes.ModeOfLon

如果您在 SQL Server Management Studio 窗口中运行上述查询,您将看到简单平均与众数+平均方法有很大不同。

由于这是一种基于集合的方法,它应该比循环/光标方法快得多。

【讨论】:

  • 我还应该提到,此方法适用于任何版本的 SQL Server。
  • 哇,非常全面的答案!我会试一试,看看我的进展如何,谢谢。
  • 我决定对原始问题使用更简单的逻辑,但我将其用于类似的事情并且效果很好。再次感谢。
  • 只是想回过头来说说,在多个不同的场景中对此进行了测试后,结果证明这是一个非常好的解决问题的方法。再次感谢 G。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-28
  • 2014-02-02
  • 2010-11-09
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
相关资源
最近更新 更多