如何在SQL Server中通过经纬度计算两点之间的距离
SQL Server 经纬度两点距离计算解决方案
方案1:修复MySQL移植的大圆距离公式
你用到的LEAST函数为MySQL原生函数,SQL Server 2022以下版本无对应内置函数,可通过IIF逻辑替换(仅用于限制ACOS输入参数范围在[-1,1],避免浮点数精度溢出报错),修改后可直接运行:
SELECT a.city AS from_city, b.city AS to_city, 111.1111 * DEGREES(ACOS(IIF( COS(RADIANS(a.Latitude)) * COS(RADIANS(b.Latitude)) * COS(RADIANS(a.Longitude) - RADIANS(b.Longitude)) + SIN(RADIANS(a.Latitude)) * SIN(RADIANS(b.Latitude)) > 1.0, 1.0, COS(RADIANS(a.Latitude)) * COS(RADIANS(b.Latitude)) * COS(RADIANS(a.Longitude) - RADIANS(b.Longitude)) + SIN(RADIANS(a.Latitude)) * SIN(RADIANS(b.Latitude)) ))) AS distance_in_km FROM #city AS a JOIN #city AS b ON a.id <> b.id WHERE a.city = 3 AND b.city = 7
如果需要计算英里,把系数111.1111替换为69.0即可。
方案2:修复近似距离公式的逻辑错误
你的第二种方案计算结果异常是因为代码存在手误:经度差计算时错误地使用a.Latitude代替了a.Longitude,修正后即可得到正确结果:
-- 修正后的查询语句 SELECT a.city AS from_city, b.city AS to_city, SQRT(POWER(69.1 * ( a.Latitude - b.Latitude), 2) + POWER(69.1 * ( b.Longitude - a.Longitude ) * COS(a.Latitude / 57.3), 2)) AS distance_in_mile FROM #city AS a JOIN #city AS b ON a.id <> b.id WHERE a.city = 3 AND b.city = 7
你写的变量版本无逻辑错误,结果可以和MySQL对齐。
推荐方案:使用SQL Server原生空间类型计算
SQL Server内置GEOGRAPHY类型可直接计算球面距离,无需手动写公式,精度更高、兼容性更好:
-- 示例:计算两点距离(单位:公里) DECLARE @source GEOGRAPHY = GEOGRAPHY::STPointFromText('POINT(61.860278 31.015833)', 4326) DECLARE @dest GEOGRAPHY = GEOGRAPHY::STPointFromText('POINT(66.078056 32.534167)', 4326) SELECT @source.STDistance(@dest) / 1000 AS distance_in_km -- 结果除以1000转公里,除以1609.344转英里
注意:STPointFromText的参数顺序是「经度在前,纬度在后」,SRID参数4326对应WGS84通用经纬度坐标系。
内容的提问来源于stack exchange,提问作者jay dublin
相关产品推荐
相关产品推荐

