You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将附近地点查询SQL转换为Laravel Eloquent ORM?

问题分析与解决方案

你遇到的A non-numeric value encountered错误,根源是直接在PHP代码里尝试执行数据库的数学函数,同时把数据库字段名(如latitude)当成字符串做数值运算,PHP无法识别这些字段的数值,自然抛出非数值错误;另外having和orderBy里的distance也没有正确声明为查询别名。

以下是正确的Laravel Eloquent转换代码:

方法一:使用DB::raw()+参数绑定

首先确保控制器顶部引入DB门面:

use Illuminate\Support\Facades\DB;

然后编写查询:

$vehicles = $vehicles->select('*', DB::raw('(3956 * 2 * ASIN(SQRT( POWER(SIN(( :lat - latitude) *  pi()/180 / 2), 2) +COS( :lat * pi()/180) * COS(latitude * pi()/180) * POWER(SIN(( :lng - longitude) * pi()/180 / 2), 2) ))) AS distance'))
    ->setBindings([
        'lat' => $request->location_lat,
        'lng' => $request->location_long
    ])
    ->having('distance', '<=', 10)
    ->orderBy('distance', 'ASC')
    ->get();

方法二:使用selectRaw()简化写法

$vehicles = $vehicles->selectRaw('*, (3956 * 2 * ASIN(SQRT( POWER(SIN(( ? - latitude) *  pi()/180 / 2), 2) +COS( ? * pi()/180) * COS(latitude * pi()/180) * POWER(SIN(( ? - longitude) * pi()/180 / 2), 2) ))) AS distance', [
    $request->location_lat,
    $request->location_lat,
    $request->location_long
])
->having('distance', '<=', 10)
->orderBy('distance', 'ASC')
->get();

关键说明

  1. DB::raw()/selectRaw()的作用:将距离计算的SQL片段包裹起来,让Laravel直接把这段内容发送给数据库执行,而非在PHP中尝试解析(PHP不认识ASIN/POWER这类数据库函数)。
  2. 参数绑定:用占位符传递经纬度,既避免SQL注入风险,又确保数值正确传递给数据库。
  3. having/orderBy的写法:将distance作为字符串参数传入,Laravel会正确识别为查询中的别名。

内容的提问来源于stack exchange,提问作者kumari shwetha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 21:25:24