【问题标题】:Finding relationship count as per latitude and longitude in Laravel App在 Laravel App 中根据经纬度查找关系计数
【发布时间】:2021-06-28 02:42:20
【问题描述】:

我正在尝试在 Laravel 上构建一个应用程序。我有一个模型Project,它有idnamestate_idcity_idlatitudelongitudestatustimestamps

我尝试添加一个附近的功能,根据纬度和经度约束找到项目。我的查询是:

$projects = Project::where('projects.status', 'saved')
    ->selectRaw("*,
     ( 6371 * acos( cos( radians(?) ) *
       cos( radians( latitude ) )
       * cos( radians( longitude ) - radians(?)
       ) + sin( radians(?) ) *
       sin( radians( latitude ) ) )
     ) AS distance", [request('latitude'), request('longitude'), request('latitude')])->having("distance", "<", request('range')
    ->with('state', 'city')
    ->orderBy('projects.updated_at', 'desc')
    ->paginate(50)

这按预期工作,现在我需要根据上述查询找出与州/城市相关的项目数量,我试过了:

$states = State::withCount(['projects' => function ($q){
    $q->selectRaw("*,
         ( 6371 * acos( cos( radians(?) ) *
           cos( radians( latitude ) )
           * cos( radians( longitude ) - radians(?)
           ) + sin( radians(?) ) *
           sin( radians( latitude ) ) )
         ) AS distance", [request('latitude'), request('longitude'), request('latitude')])->having("distance", "<", request('range')
    }])
    ->orderBy('states.name', 'desc')->paginate();

MySQL 出现错误

SQLSTATE[42S22]:未找到列:1054 未知列“距离”在“有子句”中(SQL:选择 states.,(从 projects 中选择计数()@ 987654334@.id = projects.state_id.....

什么是更好的实现方式?

【问题讨论】:

  • 我原以为任何可行的方式都“更好”。如果是我,我会从 sql 开始。

标签: php mysql laravel eloquent


【解决方案1】:
$lat = $request->latitude ?? '';
$lng = $request->longitude ?? '';
$distance = $request->range ?? '';
$states = State::query();
$states = $states::withCount(['projects' => function ($q) use ($lat,$lng,$distance){
    $haversineSQL = "( 6371 * acos( cos( radians('{$lat}') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('{$lng}') ) + sin( radians('{$lat}') ) * sin( radians( latitude ) ) ) )";
    $states = $states->whereRaw($haversineSQL . '< ?', $distance);
}])->orderBy('name', 'desc')->paginate(2);

$states = State::withCount(['projects' => function ($query) use ($lat,$lng,$distance){
        $query->select(\DB::raw('*,( COALESCE( 6371 * acos( cos( radians(' . $lat . ') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(' . $lng . ') ) + sin( radians(' . $lat . ') ) * sin( radians( latitude ) ) ) ) ) AS distance'))->having('distance', '<', $distance );
    }])->orderBy('name', 'desc')->paginate(2);

【讨论】:

    【解决方案2】:

    问题很可能是 Eloquent 在 having() 调用中将数据库和表名前缀为 distance

    由于distance 是在selectRaw 中创建的别名,因此您需要使用havingRaw()https://laravel.com/docs/8.x/queries#havingraw-orhavingraw

    -&gt;havingRaw('distance &lt; ?', request('range'))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-07
      • 2020-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-07
      相关资源
      最近更新 更多