2

緯度/経度座標を使用して2点間の距離を計算するSQL関数があります。この関数を使用すると、次のように、特定のポイントの距離に基づいて、大きなセット( GEOCODESテーブル)から場所のセットを候補リストに入れることができます。

DECLARE @LAT1 float, @LNG1 float,
SET @LAT1 = '34.169540'
SET @LNG1 = '-92.590990'

SELECT E.* FROM GEOCODES E
WHERE dbo.fnGetDistance(E.lat, E.lng, @LAT1, @LNG1, 'miles') < '20'

次の形式のポイント間の距離を示す2番目のテーブル(GEOMILES )があります。

LOCATION1  | STATE1  |  LOCATION2  |  STATE2  | DISTANCE
-----------+---------+-------------+----------+---------
New York   |   NY    |    Boston   |   MA     |   220

私が達成しようとしているのはSELECT、出発点がニューヨークから20マイル以内にあり、到着点がボストンから20マイル以内にある場合に、220の距離を返すクエリです。これまでのところ、これはありますが、lat / lngポイントなどが加算されることを手動で確認しても、何も返されません。どんな助けでも大歓迎です!

DECLARE @FROM_LOC VARCHAR(100), @FROM_STA VARCHAR(2), @TO_LOC VARCHAR(100), @TO_STA VARCHAR(2)

SET @FROM_LOC = 'NEWARK'
SET @FROM_STA = 'NJ'

SET @TO_LOC = 'MEDFORD'
SET @TO_STA = 'MA'      

SELECT G.DIST FROM GEOMILES G, GEOCODES E
JOIN GEOCODES C ON C.asciiname = @FROM_LOC AND C.admin1 = @FROM_STA
JOIN GEOCODES D ON D.asciiname = @TO_LOC AND D.admin1 = @TO_STA
WHERE dbo.fnGetDistance(E.lat, E.lng, C.lat, C.lng, 'miles') < '20'
AND dbo.fnGetDistance(E.lat, E.lng, D.lat, D.lng, 'miles') < '20'
4

3 に答える 3

1

これがあなたが求めているものだと思います(テーブル構造を使用)。。。

SELECT G.DIST
FROM GEOMILES G
, GEOCODES F --from airport
, GEOCODES E --to airport
, GEOCODES C --from location
, GEOCODES D --to location

WHERE C.asciiname = @FROM_LOC 
AND C.admin1 = @FROM_STA

AND D.asciiname = @TO_LOC 
AND D.admin1 = @TO_STA

AND dbo.fnGetDistance(F.lat, F.lng, C.lat, C.lng, 'miles') < 20
AND dbo.fnGetDistance(E.lat, E.lng, D.lat, D.lng, 'miles') < 20

and G.Location1 = F.asciiname
and G.Location2 = E.asciiname
and G.State1 = F.admin1
and G.State2 = E.admin1

代替バージョン(これはパフォーマンスが向上すると思います)

SELECT G.DIST
FROM GEOMILES G
inner join
(
    select fromAirport.asciiname
    , fromAirport.admin1
    from GeoCodes fromAirport
    where exists
    (
        select top 1 1
        from GeoCodes fromLocation
        where fromLocation.asciiname = @FROM_LOC
        and fromLocation.admin1 = @FROM_STA
        and dbo.fnGetDistance(fromLocation.lat, fromLocation.lng, fromAirport.lat, fromAirport.lng, 'miles') < 20
    )
) fromA
    on G.Location1 = fromA.asciiname
    and G.State1 = fromA.admin1
inner join
(
    select toAirport.asciiname
    , toAirport.admin1
    from GeoCodes toAirport
    where exists
    (
        select top 1 1
        from GeoCodes toLocation
        where toLocation.asciiname = @TO_LOC
        and toLocation.admin1 = @TO_STA
        and dbo.fnGetDistance(toLocation.lat, toLocation.lng, toAirport.lat, toAirport.lng, 'miles') < 20
    )
) toA
    on G.Location1 = toA.asciiname
    and G.State1 = toA.admin1
于 2012-10-18T23:10:38.207 に答える
0

条項を確認してください。開始位置WHERE終了位置の両方から20マイル以内にあるすべてのコードを探しているようです。これはすでに220マイル離れていると指定しています。

また、明示JOIN的なものと暗黙的なものを混在させています(コンマ区切りFROM句)。すべての結合を明示的に修飾してください。とりわけ、どのように、GそしてどのようEに相互に関係することになっていますか?

于 2012-10-18T22:22:31.750 に答える
0

これが解決策の私の試みです-テーブルのスクリプトを保存するためにここでGEOGRAPHYを使用しましたが、うまくいけば、これをニーズに合わせて簡単に調整できます-そうでない場合は、私に知らせてください。私は適応します:

--setup
    declare @OneMileInMeters int = 1609

    declare @t table
    (
        id bigint not null identity(1,1) primary key clustered
        , name nvarchar(64)
        , lat float
        , long float
        , geo geography null
    )

    insert @t
          select 'Seattle', 47.455, -122.2310, null
    union select 'Boston',  42.372,  -71.0298, null
    union select 'Chicago', 41.953,  -87.6430, null
    union select 'Spokane', 47.668, -117.5290, null
    union select 'Philly',  39.888,  -75.2510, null
    union select 'NY',      40.7142, -74.0064, null
    union select 'Newark',  40.7356, -74.1728, null
    union select 'Medford', 42.4183, -71.1067, null

    update @t
    set geo = geography::Point(lat, long, 4326)

--query
    declare @fromLoc nvarchar(64) = 'Newark'
    , @toLoc nvarchar(64) = 'Medford'
    , @maxDistanceToAirport int = 20 * @OneMileInMeters


    select f2.name AirportFrom, t2.name AirportTo, f2.geo.STDistance(t2.geo) / @OneMileInMeters FlightDistance
    from @t f
    , @t t
    , @t f2
    , @t t2
    where f.name = @fromLoc
    and t.name = @toLoc
    and f.geo.STDistance(f2.geo) < @maxDistanceToAirport    
    and t.geo.STDistance(t2.geo) < @maxDistanceToAirport
    and t.id != t2.id
    and f.id != f2.id
于 2012-10-18T22:49:03.667 に答える