我有两张桌子,上面有沃尔玛地点,我想知道一张桌子上的哪家沃尔玛距离另一家地点的沃尔玛最近。
如果可能的话,这将是结果:
Source ClosestToSource DistanceInMeters
-----------------------------------------------------
Walmart1 Walmart8 2637.37
Walmart2 Walmart5 2047.19
Walmart3 Walmart8 1191.31
Walmart4 Walmart7 3340.33
这基本上是说,@Source
中距离
Walmart1最近的沃尔玛是
@Dest
中的Walmart8。
IF OBJECT_ID('dbo.WSource', 'U') IS NOT NULL
DROP TABLE dbo.WSource;
IF OBJECT_ID('dbo.WDest', 'U') IS NOT NULL
DROP TABLE dbo.WDest;
CREATE TABLE dbo.WSource
(
Id int IDENTITY,
StoreName varchar(15),
Lat float,
Lon float,
GeoLocation geography
)
CREATE TABLE WDest
(
Id int IDENTITY,
StoreName varchar(15),
Lat float,
Lon float,
GeoLocation geography
)
INSERT INTO WSource (StoreName, Lat, Lon)
select 'Walmart1', 28.064924, -81.652854 union
select 'Walmart2', 28.073512, -81.655092 union
select 'Walmart3', 28.063939, -81.665558 union
select 'Walmart4', 28.061616, -81.630152
update WSource
set geolocation = geography::STPointFromText('POINT(' + CAST(Lon AS VARCHAR(20)) + ' ' +
CAST(Lat AS VARCHAR(20)) + ')', 4326)
insert into WDest (StoreName, Lat, Lon)
select 'Walmart5', 28.078024, -81.675264 union
select 'Walmart6', 28.079128, -81.693943 union
select 'Walmart7', 28.089832, -81.642243 union
select 'Walmart8', 28.062409, -81.677583
update WDest
set geolocation = geography::STPointFromText('POINT(' + CAST(Lon AS VARCHAR(20)) + ' ' +
CAST(Lat AS VARCHAR(20)) + ')', 4326)
SELECT WSource.geolocation.STDistance(WDest.geolocation)
FROM WSource
CROSS JOIN WDest
这显示了从一个位置到另一个位置的所有距离,但这就是我陷入困境的地方。我正在考虑使用
RANK()
函数,但我不确定如何实现。
根据上面的结果,最接近Walmart2的是Walmart5,但不确定如何实现。
或者也许有更好的方法?
一个选项是
APPLY
和 TOP (1)
。
SELECT
WSource.StoreName AS Source,
WDest.StoreName AS ClosestToSource,
WDest.DistanceToSource
FROM WSource
CROSS APPLY (
SELECT TOP (1)
WDest.*,
WSource.geolocation.STDistance(WDest.geolocation) AS DistanceToSource
FROM WDest
ORDER BY DistanceToSource
) WDest;
您还可以使用排名功能
SELECT
w.*
FROM (
SELECT
WSource.StoreName AS Source,
WDest.StoreName AS ClosestToSource,
WSource.geolocation.STDistance(WDest.geolocation) AS DistanceToSource,
ROW_NUMBER() OVER (PARTITION BY WSource.Id ORDER BY WSource.geolocation.STDistance(WDest.geolocation)) AS rn
FROM WSource
CROSS JOIN WDest
) w
WHERE w.rn = 1;
性能差异可能取决于您是否有支持的空间索引:如果有,前者的性能会非常好,但如果没有,则性能会很差。
您可能还想检查计算从源到目标的距离是否更快,反之亦然。