screechOwl
screechOwl

Reputation: 28139

SQL Server calculate distances between 2 sets of columns of latitude / longitude

I'm trying to calculate the closest weather station to a given zip code. I have data with the lat/lon for the weather station and the zip codes. I also have a way to calculate distance for a 2 points (here). What I'm looking for is a way to create a column that has the distances for multiple instances.

StationNum  lat     lon     Zip     lat      lon   distance
123         34.66   98.32   12345   33.78   91.91   ???
456         33.03   96.8    23456   35.23   92.23   ???
789         32.29   96.85   34567   33.09   92.68   ???

Is there a way to do that or do I need to write out the math by hand?

Upvotes: 4

Views: 11020

Answers (1)

John Cappelletti
John Cappelletti

Reputation: 81930

With the GEOGRAPHY type

You had duplicate field names so I renamed them to Lat1/Lon1 and Lat2/Lon2. If this is a join, add the alias a.lat/a.lon b.lat/b.lon.

Example

Declare @YourTable Table ([StationNum] varchar(50),[lat1] float,[lon1] float,[Zip] varchar(50),[lat2] float,[lon2] float)
Insert Into @YourTable Values 
 (123,34.66,98.32,12345,33.78,91.91)
,(456,33.03,96.8,23456,35.23,92.23)
,(789,32.29,96.85,34567,33.09,92.68)

Select * 
      ,InMeters = GEOGRAPHY::Point([Lat1], [Lon1], 4326).STDistance(GEOGRAPHY::Point([Lat2], [Lon2], 4326))
      ,InMiles  = GEOGRAPHY::Point([Lat1], [Lon1], 4326).STDistance(GEOGRAPHY::Point([Lat2], [Lon2], 4326)) / 1609.344
 from @YourTable

Returns

enter image description here

Edit - For your consideration

Consider adding a Geography field to your source table(s). This will eliminate the redundant GEOGRAPHY::Point() function calls

Update YourTable Set GeoPoint = GEOGRAPHY::Point([Lat], [Lon], 4326)

So then the calculation for distance would simply be

  ,InMeters  = A.GeoPoint.STDistance(B.GeoPoint) 
  ,InMiles   = A.GeoPoint.STDistance(B.GeoPoint) / 1609.344

Upvotes: 5

Related Questions