使用SQL Server 2014。
我正在尝试让SQL Server计算世界各地机场之间的距离,以公里,英里和航海里程为单位。大多数情况下,下面的方法有效,但当距离超过10,000公里时它似乎失败了(尽管这只是一个假设)。
DECLARE @Radius_Km AS FLOAT
DECLARE @Radius_Mi AS FLOAT
DECLARE @Radius_Nm AS FLOAT
DECLARE @Pi AS FLOAT
DECLARE @D2R AS FLOAT
SET @Radius_Km = '6370.97327862'
SET @Radius_Mi = '3958.73926185'
SET @Radius_Nm = '3440.05036642'
SET @Pi = '3.14159265358979'
SET @D2R = @Pi / 180;
WITH RawData AS
(
SELECT DISTINCT Sched.AirlineName, Sched.AirlineIATA, Sched.AirlineICAO, Sched.FlightNo,
Sched.DepartureAirportName, Sched.DepartureAirportIATA, DepAprt.AirportICAO AS [DepartureAirportICAO],
DepAprt.Latitude AS [DepartureAirportLatitude], DepAprt.Longitude AS [DepartureAirportLongitude],
Sched.ArrivalAirportName, Sched.ArrivalAirportIATA, ArrAprt.AirportICAO AS [ArrivalAirportICAO],
ArrAprt.Latitude AS [ArrivalAirportLatitude], ArrAprt.Longitude AS [ArrivalAirportLongitude]
FROM VAS_Live.dbo.RawData_FR24 AS Sched
LEFT JOIN VAS_Live.dbo.ReferenceData_Airports AS DepAprt
ON Sched.DepartureAirportIATA = DepAprt.AirportIATA
LEFT JOIN VAS_Live.dbo.ReferenceData_Airports AS ArrAprt
ON Sched.ArrivalAirportIATA = ArrAprt.AirportIATA
),
RadianConvert AS
(
SELECT *,
((DepartureAirportLatitude / 180) * @Pi) AS [DALat],
((DepartureAirportLongitude / 180) * @Pi) AS [DALon],
((ArrivalAirportLatitude / 180) * @Pi) AS [AALat],
((ArrivalAirportLongitude / 180) * @Pi) AS [AALon]
FROM RawData
),
CentralSphericalAngle AS
(
SELECT *,
(Sin(DALat) * Sin(AALat)) + (Cos(DALat) * Cos(AALat) * Cos(AALon - DALon)) AS [Test]
FROM RadianConvert
),
TestCTE AS
(
SELECT *,
@Radius_Mi * ATAN(SQRT(1 - POWER(Test, 2)) / Test) AS [Test2]
FROM CentralSphericalAngle
)
SELECT *
FROM TestCTE
WHERE DepartureAirportIATA = 'LHR' AND ArrivalAirportIATA = 'SIN'
对于上面的例子,LHR Lat& Lon如下:
51.4775 -0.461389
SIN Lat&长期如下:
1.35019 103.994
我已经知道距离大致是:
公元 - 10,883Mi - 6,762
Nm - 5,876
知道SQL为什么给我-5674?
我曾经使用VBA和Excel来计算这些数据,这是有效的。我注意到了抵达AALat&转换为Radians时DALon计算错误 - 但我不知道为什么。
由于
马修
答案 0 :(得分:2)
从Lat&amp ;;计算距离(英里)函数。 Lon as by:
CREATE FUNCTION [dbo].[getDistanceFromLatLon](@lat1 float, @lon1 float, @lat2 float, @lon2 float)
Returns float
AS
BEGIN
Declare @R int
set @R= 6371;
Declare @a float
Declare @c float
Declare @d float
Declare @dLat float;
Declare @dLon float;
declare @DegToRad float
BEGIN
set @DegToRad= (select PI() / 180)
set @dLat = (@lat2 - @lat1)* @DegToRad;
set @dLon = (@lon2 - @lon1)* @DegToRad;
set @a = sin(@dLat / 2) * sin(@dLat / 2) +
cos((@lat1)* @DegToRad) * cos((@lat2)* @DegToRad) *
sin(@dLon / 2) * sin(@dLon / 2) ;
set @c = 2 * atn2(sqrt(@a), sqrt(1 - @a));
set @d = @R * @c;
END
return (@d * 0.6214)
END
从这个功能,
DECLARE @Kilimiles float
DECLARE @miles float
DECLARE @nauticalmile float
SET @miles=(SELECT dbo.[getDistanceFromLatLon](51.4775, -0.461389,1.35019 ,103.994))
SET @Kilimiles=@miles * 1.60934
SET @nauticalmile= @miles * 0.868976
SELECT @miles as Mile,@Kilimiles as Kilomile,@nauticalmile as NauticalMile