2013-04-30 124 views
1

鑑於以下SQL返回基於給定城市的機場列表,我將如何進一步增強它以按最接近我的方式對結果進行排序?它似乎應該很簡單,但它逃避了我。SQL Server:查找最近的位置

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; 
+0

SQL有一個pi常量,['PI()'](http://msdn.microsoft.com/en-us/library/ms189512.aspx)。除非你有意將其舍入到特定值,否則你並不需要對其進行硬編碼。 – valverij 2013-04-30 18:40:29

+3

您的SQL Server版本是否支持地理空間數據類型? – JOBG 2013-04-30 18:44:36

+0

目前經緯度和緯度都是以浮標形式存儲的 – Matt 2013-04-30 18:50:22

回答

4

@hatchet是正確的..假設你的SQL Server支持geography spatial data實例,那麼你應該考慮使用的數據類型的計算,你也可能會發現一些有用的這個代碼,只需更換表名,條件根據需要和分頁:

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 
+0

如果OP沒有內置的地理功能可用,他們可以使用這個SQL UDF:http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=81360 – hatchet 2013-04-30 19:51:59

2

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

我相信,在SQL Server 2000中,排序上的計算值則必須在複製的順序計算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 

附:但在更高版本的SQL中,您可以對列別名進行排序。

無論如何,您必須有一列包含計算出的距離。