0

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

举个例子来说明一下:我们需要锁定一个项目的 GPS 坐标,所以我们要求用户在他们处于项目的大致区域时按下一个按钮,并记录 GPS 坐标。然后我们取其中的 5 个并将项目的位置设置为 AVG(Location.Lat) + AVG(Location.Long)。当其中一个用户按下数英里外,抛出平均值时,就会出现问题,因此现在需要识别其中的任何一个。

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

4

1 回答 1

2

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

我建议您看一下我几年前写的这篇博客:使用 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 窗口中运行上述查询,您将看到简单平均与模式+平均方法有很大不同。

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

于 2014-07-09T12:45:18.037 回答