2

我有两张桌子:

CREATE TABLE [dbo].[Gps] (
    [Date] [datetime] NOT NULL,
    [Latitude] [decimal](9, 6) NOT NULL,
    [Longitude] [decimal](9, 6) NOT NULL
)

CREATE TABLE [dbo].[Stops] (
    [StopName] [varchar](128) NOT NULL,
    [StopLat] [decimal](9, 6) NOT NULL,
    [StopLon] [decimal](9, 6) NOT NULL
)

我想使用我用这个签名编写的 Haversine() 标量函数为每个 Gps 条目获取最近的停止:

CREATE FUNCTION [dbo].[Haversine]
(
    @aLatitude  DECIMAL(9, 6),
    @aLongitude DECIMAL(9, 6),
    @bLatitude  DECIMAL(9, 6),
    @bLongitude DECIMAL(9, 6)
)
RETURNS DECIMAL(16, 6)

例子:

SELECT dbo.Haversine(0.0, 0.0, 0.0, 0.0)

我想同时获得 StopName 以及 Haversine 函数的结果。我将如何有效地做到这一点?

4

3 回答 3

2
select [Date],Latitude,Longitude,StopName,StopLat,StopLon, dbo.Haversine(Latitude,Longitude,StopLat,StopLon) as distance 
INTO #Distances 
from GPS,STOPS;

select * from #Distances d
join 
(
select [Date],min(distance) minDist from #Distances group by [Date]
) B on (d.[date]=B.[date]) and (d.distance=b.minDist);

请注意,如果与两个 STOPS 的最小距离相等,则此查询可以为一个 GPS 位置选择多行。主要的性能问题在于第一个查询(创建临时#Distance 表)。

我认为您应该通过 WHERE 语句优化此查询以减少输出表。例如,您可以设置从 GPS 位置到任何 STOP 位置的最大允许距离并添加WHERE dbo.Haversine(Latitude,Longitude,StopLat,StopLon)<MAX_ALLOWED_DISTANCE.

于 2012-08-02T12:49:00.363 回答
0

此查询应该有效:

SELECT  Gps.*, Stops.*
FROM    Gps
JOIN    Stops   
        ON (dbo.Haversine(Latitude, Longitude, StopLat, StopLon) 
            = (SELECT MIN(dbo.Haversine(Latitude, Longitude, s2.StopLat, s2.StopLon))
                FROM    Stops As s2
            ) )

但它肯定不会很快。


这是另一种应该起作用的方法:

;WITH
  cte As
(
    SELECT  Gps.*, Stops.*,
            dbo.Haversine(Latitude, Longitude, StopLat, StopLon) As distance,
            MIN(dbo.Haversine(Latitude, Longitude, StopLat, StopLon))
                    OVER(Partition By Latitude, Longitude)       As minDistance
    FROM    Gps
    CROSS JOIN
            Stops
)
SELECT  *, distance
FROM    cte
WHERE   distance = minDistance

不过还是一样慢。

于 2012-08-02T03:15:01.300 回答
0

鉴于您使用的是 SQL Server 2008,我建议使用内置geography数据类型存储您的 GPS 和 STOP 点,并使用内置STDistance函数来测量距离。

于 2012-08-02T08:13:53.913 回答