1

鉴于以下 SQL 返回基于给定城市的机场列表,我将如何进一步增强它以按离我最近的地方对结果进行排序?看起来它应该很简单,但它让我难以理解。

DECLARE @latRange float
DECLARE @LongRange float
DECLARE @LowLatitude float
DECLARE @HighLatitude float
DECLARE @LowLongitude float
DECLARE @HighLongitude float
DECLARE @Radius float = 100


DECLARE @istartlat float
DECLARE @istartlong float

Select @istartlat=Latitude, @istartlong=Longitude from Lookup where PlaceName = '"Franklin"' and StateCode = '"AR"'

Select @latRange = @Radius / ((6076 / 5280) * 60)
Select @LongRange = @Radius / (((COS((@istartlat * 3.14592653589 / 180)) * 6076.) / 5280. * 60))

Select @LowLatitude = @istartlat - @latRange
Select @HighLatitude = @istartlat + @latRange
Select @LowLongitude = @istartlong - @LongRange
Select @HighLongitude = @istartlong + @LongRange

Select a.City, a.State, a.AirportCode, a.AirportName, a.CountryCode
from PFM_Airport a
where (a.Latitude <= @HighLatitude) and (a.Latitude >= @LowLatitude) and (a.Longitude >= @LowLongitude)
and (a.Longitude <= @HighLongitude)
--and a.CountryCode in ('USA', 'CANADA')
order by a.Latitude, a.Longitude;
4

2 回答 2

4

@hatchet 是对的。假设您的 SQL Server 实例支持地理空间数据,那么您应该考虑使用该数据类型进行计算,您还可能会发现其中一些代码很有用,只需根据需要替换表名、条件和分页:

ALTER PROCEDURE [dbo].[SP_NearestPOIReloaded]
(
    -- Add the parameters for the stored procedure here
    @LAT float,
    @LNG float,
    @DISTANCE int,
    @CURRENTPAGE Int,
    @PAGESIZE Int,
    @COUNT int OUTPUT
    )
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

/*for pagination*/
SET @COUNT = (SELECT COUNT(*) FROM dbo.Lugares as [L] WHERE dbo.DistanceBetween(@LAT, @LNG, [L].lat, [L].lng) < @DISTANCE)

/*paginated resultset*/
SELECT * FROM (
SELECT ROW_NUMBER()Over(Order by dbo.DistanceBetween(@LAT, @LNG, [L].lat, [L].lng) Asc) As [RowNum], dbo.DistanceBetween(@LAT, @LNG, [L].lat, [L].lng) as [distance], [L].*, [E].name as [empresaName], [U].userName as [userName]
FROM dbo.Lugares as [L], dbo.Empresas as [E], dbo.Usuarios as [U]
WHERE dbo.DistanceBetween(@LAT, @LNG, [L].lat, [L].lng) < @DISTANCE AND
[L].usuarioId = [U].id AND [L].empresaId = [E].id
)
AS ResultadoPaginado
WHERE RowNum BETWEEN (@CURRENTPAGE - 1) * @PAGESIZE + 1 AND @CURRENTPAGE * @PAGESIZE

END

这取决于一个名为 DistanceBetween 的函数(如果您的实例不支持空间数据类型,那么这是您必须用您自己的代码的变体替换的部分):

ALTER FUNCTION [dbo].[DistanceBetween] 
(   
    -- Add the parameters for the function here
    @PIVOTE_LAT as float,
    @PIVOTE_LNG as float,
    @LAT as float,
    @LNG as float
)

returns real
as begin
declare @distance real;

declare @PIVOTE_POINT geography = geography::Point(@PIVOTE_LAT,@PIVOTE_LNG, 4326);
declare @POINT geography = geography::Point(@LAT,@LNG, 4326);

set @distance = @PIVOTE_POINT.STDistance(@POINT);
return (@distance);
end
于 2013-04-30T18:57:11.643 回答
2

how would I further enhance it to sort the results by what's nearest to me?

我相信在 SQL Server 2000 中,要对计算值进行排序,您必须在 ORDER BY 子句中复制计算,ORDER BY < the calculation>或者您可以这样做:

      select FOO.a, FOO.b, FOO.myvalue
      from
      (
      select a, b, <some calculation> as myvalue
      from T
      where <some calculation>  <= {some value}
      ) as FOO
      order by FOO.myvalue

PS 但是在更高版本的 SQL 中,您可以对列别名进行排序。

在任何情况下,您都必须有一列来包含计算出的距离。

于 2013-04-30T19:07:12.867 回答