编辑:(如果您想查看旧问题,请参阅此问题的底部)
在您的帮助下,我修改了我的声明:
SELECT *
FROM (
SELECT
dest.ZC_ZIP,
dest.ZC_LOCATION_NAME,
ACOS(
SIN(RADIANS(src.ZC_LAT)) * SIN(RADIANS(dest.ZC_LAT))
+ COS(RADIANS(src.ZC_LAT)) * COS(RADIANS(dest.ZC_LAT))
* COS(RADIANS(src.ZC_LON) - RADIANS(dest.ZC_LON))
) * 6371 AS DISTANCE
FROM USER.ZC_COORDINATES dest
CROSS JOIN USER.ZC_COORDINATES src
WHERE src.ZC_ID =
(SELECT
ZC_ID
FROM USER.ZC_COORDINATES
WHERE ZC_ZIP = '64289'
GROUP BY ZC_ID
)
AND
(dest.ZC_ID <> src.ZC_ID OR dest.ZC_ID = src.ZC_ID)
)
HAVING DISTANCE <= 25 /* km */
ORDER BY DISTANCE;
此后我收到错误:“Radians”是无效标识符。
原因:Oracle 实现了该功能(MySQL 实现了!)。
所以我搜索并找到了这段代码并使用它:
CREATE OR REPLACE FUNCTION calc_distance(pLat1 NUMBER, pLon1 NUMBER, pLat2 NUMBER, pLon2 NUMBER)
RETURN NUMBER IS
-- r is the spherical radius of earth in Kilometers
cSpherRad CONSTANT NUMBER := 6371;
-- The spherical radius of earth in miles is 3956
a NUMBER;
vLat NUMBER;
vLat1Rad NUMBER;
vLat2Rad NUMBER;
vLon NUMBER;
vLon1Rad NUMBER;
vLon2Rad NUMBER;
BEGIN
/*
Most computers require the arguments of trigonometric functions to be
expressed in radians. To convert lon1, lat1 and lon2,lat2 from
degrees,minutes, seconds to radians, first convert them to decimal
degrees. To convert decimal degrees to radians, multiply the number
of degrees by pi/180 = 0.017453293 radians/degrees.
*/
vLat1Rad := pLat1 * 0.017453293;
vLat2Rad := pLat2 * 0.017453293;
vLon1Rad := pLon1 * 0.017453293;
vLon2Rad := pLon2 * 0.017453293;
vLon := vLon2Rad - vLon1Rad;
vLat := vLat2Rad - vLat1Rad;
a := POWER(SIN(vLat/2),2) + COS(vLat1Rad) * COS(vLat2Rad) * POWER(SIN(vLon/2),2);
/*
The intermediate result c is the great circle distance in radians.
Inverse trigonometric functions return results expressed in radians.
To express c in decimal degrees, multiply the number of radians by
180/pi = 57.295780 degrees/radian.
The great circle distance d will be in the same units as r.
*/
RETURN ROUND(cSpherRad * 2 * ATAN2(SQRT(a), SQRT(1-a)),1);
EXCEPTION
WHEN OTHERS THEN
RETURN 999;
END calc_distance;
/
编译成功。
现在正确的修改没有分组错误:
SELECT *
FROM (
SELECT
dest.ZC_ZIP AS ZIP,
dest.ZC_LOCATION_NAME AS LOCNAME,
calc_distance(src.ZC_LAT, src.ZC_LON, dest.ZC_LAT, dest.ZC_LON) AS DISTANCE
FROM BASE.ZC_COORDINATES dest
CROSS JOIN BASE.ZC_COORDINATES src
WHERE src.ZC_ID =
(SELECT
ZC_ID
FROM BASE.ZC_COORDINATES
WHERE ZC_ZIP = '64289'
GROUP BY ZC_ID
)
AND
(dest.ZC_ID <> src.ZC_ID OR dest.ZC_ID = src.ZC_ID)
)
HAVING DISTANCE <= 25 /* km */
GROUP BY ZIP, LOCNAME, DISTANCE;
--ORDER BY DISTANCE;
现在有什么问题吗?
好的,在我的旧本地 MySQL 系统上,我得到这些 sql 结果(正确的解决方案):
zc_zip zc_location_name distance
64291 Darmstadt 0
64297 Darmstadt 0
64289 Darmstadt 0
64283 Darmstadt 0
64285 Darmstadt 0
64295 Darmstadt 0
64293 Darmstadt 0
64287 Darmstadt 0
64347 Griesheim, Hessen 5.385545333978872
64331 Weiterstadt 5.671376373674798
64367 M├╝hltal, Hessen 6.992565870106159
64319 Pfungstadt 7.7621346384241585
64380 Roßdorf bei Darmstadt 8.134881711148836
64372 Ober-Ramstadt 8.421977582053422
64390 Erzhausen, Hessen 9.419234655429722
64572 B├╝ttelborn 9.739076077060767
64409 Messel 9.962635340560048
63329 Egelsbach, Hessen 11.274247321555363
64342 Seeheim-Jugenheim 11.743554066395413
64560 Riedstadt 12.135040456984065
64404 Bickenbach 12.597317271640899
64521 Groß-Gerau 12.637599535794854
64397 Modautal 13.260629389533909
64846 Groß-Zimmern 13.270265030251164
63225 Langen (Hessen) 13.745513110307494
这是我从预言机系统得到的:
ZIP LOCNAME DISTANCE
64293 Darmstadt 0
64283 Darmstadt 0
64295 Darmstadt 0
64285 Darmstadt 0
64297 Darmstadt 0
64287 Darmstadt 0
64289 Darmstadt 0
64291 Darmstadt 0
您看,缺少一些结果。 我认为问题出在oracle语句中的“GROUP BY”行,这是必需的。 所以我无法删除这一行。但我怎样才能得到其他结果呢?我真的很困惑:(
<小时/>(老问题)
目前,我为我的员工编写了一个循环邮政编码搜索。 我的工具正在我的 MySQL 数据库(本地)上运行。
现在我将 OpenGeoDB 迁移到我们的 Oracle 数据库(成功),并希望运行我的 sql 语句,该语句在我的本地 MySQL 数据库上完美运行。
完整的错误消息:
ORA-00904: "DISTANCE": invalid indentifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Error in line: 20 col: 7
我的SQL语句:
SELECT
dest.zc_zip,
dest.zc_location_name,
ACOS(
SIN(RADIANS(src.zc_lat)) * SIN(RADIANS(dest.zc_lat))
+ COS(RADIANS(src.zc_lat)) * COS(RADIANS(dest.zc_lat))
* COS(RADIANS(src.zc_lon) - RADIANS(dest.zc_lon))
) * 6371 as distance
FROM USER.ZC_COORDINATES dest
CROSS JOIN USER.ZC_COORDINATES src
WHERE src.zc_id =
(
SELECT zc_id
FROM USER.zip_coordinates
WHERE zc_zip = '64289' /* Platzhalter fuer PLZ */
GROUP BY zc_zip
)
AND (dest.zc_id <> src.zc_id OR dest.zc_id = src.zc_id)
HAVING distance <= 25 /* km */
ORDER BY distance;
我该如何解决这个问题?: 我用完整的数学计算切换了“距离”一词,但在此之后,Oracle 调用无效标识符“弧度”
这就是我的问题,因为我不知道如何解决这个问题。
有人有解决这个问题的想法吗?
谢谢。
最佳答案
Oracle 不允许您在以下 ORDER BY 中使用在 SELECT 列表中计算的列。以下是合理的解决方法:
SELECT *
FROM (SELECT dest.ZC_ZIP,
dest.ZC_LOCATION_NAME,
ACOS(SIN(RADIANS(src.ZC_LAT)) * SIN(RADIANS(dest.ZC_LAT))
+ COS(RADIANS(src.ZC_LAT)) * COS(RADIANS(dest.ZC_LAT))
* COS(RADIANS(src.ZC_LON) - RADIANS(dest.ZC_LON))
) * 6371 AS DISTANCE
FROM USER.ZC_COORDINATES dest
CROSS JOIN USER.ZC_COORDINATES src
WHERE src.ZC_ID = (SELECT ZC_ID
FROM USER.ZIP_COORDINATES
WHERE ZC_ZIP = '64289'
GROUP BY ZC_ZIP) AND
(dest.ZC_ID <> src.ZC_ID OR
dest.ZC_ID = src.ZC_ID))
HAVING DISTANCE <= 25 /* km */
ORDER BY DISTANCE;
Oracle 也不提供将度数转换为弧度的函数,但添加您自己的函数很容易:
CREATE OR REPLACE FUNCTION RADIANS(nDegrees IN NUMBER) RETURN NUMBER DETERMINISTIC IS
BEGIN
-- radians = degrees / (180 / pi)
-- RETURN nDegrees / (180 / ACOS(-1)); -- but 180/pi is a constant, so...
RETURN nDegrees / 57.29577951308232087679815481410517033235;
END RADIANS;
分享并享受。
关于mysql - Oracle圆距离搜索: missing results,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24937868/