Pee*_*Haa 5 php postgresql pdo haversine
在我的网站上,我正试图在附近找到位置.
我正在尝试使用Haversine公式.
我正在使用以下查询来获取25公里范围内的所有位置.
SELECT id, ( 6371 * acos( cos( radians(51.8391) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(4.6265) ) + sin( radians(51.8391) ) * sin( radians( lat ) ) ) ) AS distance
FROM shops
HAVING distance < 25
ORDER BY name asc
Run Code Online (Sandbox Code Playgroud)
但是我觉得有些函数可能只是MySQL,因为我收到以下错误:
警告:PDOStatement :: execute()[pdostatement.execute]:SQLSTATE [42883]:未定义的函数:7错误:函数弧度(文本)不存在LINE 1:... id,(6371*acos(cos(radians( 51.8391))*cos(弧度(l ... ^ HINT:没有函数匹配给定的名称和参数类型.你可能需要添加显式类型转换.in ...
或者它可能与我必须更改lat查询中的文本有关.但我不知道应该是什么.
51.8391和4.6265是我的"起点"的长点和长点.
任何帮助都非常感谢,因为我不知道要改变什么:-)
编辑
看起来问题出在我试图做的地方:radians(lat).
lat是我表中的一列.
当我尝试使用rad()hakre建议错误更改为:function rad(numeric) does not exist
编辑2
现在我们到了某个地方.
确实设置为文本的列的数据类型(由mu建议的太短).
我把它改为双精度.
但是现在我又得到了一个错误:
警告:PDOStatement :: execute()[pdostatement.execute]:SQLSTATE [42703]:未定义列:7错误:列"距离"不存在第1行:... adians(lat))))AS距离商店HAVING距离<... ^ ...
但我以为我在选择中做了一个别名.有任何想法吗?
此外,如果你们认为这应该是另一个问题,请告诉我,我会关闭这个.
PostgreSQL确实有一个radians功能:
radians(dp)
度数到弧度
但是radians想要一个浮点参数,你试图给它一些字符串:
未定义的函数:7错误:函数弧度(文本)
[...]提示:没有函数匹配给定的名称和参数类型.您可能需要添加显式类型转换.
强调我的.显然,你lat和lng列char(n),varchar(n)或text列.你应该修改列类型lat和lng要numeric,float或一些其他浮点类型 ; 同时,您可以手动投射字符串,并希望您没有任何损坏的数据:
radians(cast(lat as double precision))
Run Code Online (Sandbox Code Playgroud)
MySQL做了很多隐式类型转换,PostgreSQL更严格,要求你准确地说出你的意思.
第二个问题的更新:在HAVING子句之前计算SELECT子句,因此SELECT查询中的其他位置通常不提供列别名.你有几个选择,你可以重复你的丑陋的Haversine:
SELECT id, ( 6371 * acos( cos( radians(51.8391) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(4.6265) ) + sin( radians(51.8391) ) * sin( radians( lat ) ) ) ) AS distance
FROM shops
HAVING ( 6371 * acos( cos( radians(51.8391) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(4.6265) ) + sin( radians(51.8391) ) * sin( radians( lat ) ) ) ) < 25
ORDER BY name asc
Run Code Online (Sandbox Code Playgroud)
或者使用派生表来避免重复自己:
select id, distance
from (
select id, name, ( 6371 * acos( cos( radians(51.8391) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(4.6265) ) + sin( radians(51.8391) ) * sin( radians( lat ) ) ) ) as distance
from shops
) as dt
where distance < 25.0
order by name asc
Run Code Online (Sandbox Code Playgroud)