Mir*_* Vu 7 mysql laravel eloquent laravel-5
我需要抓住"经销商"关系距离<200的车辆
Vehicle::join('dealers', 'vehicles.dealer_id', '=', 'dealers.id')
->select(DB::raw("dealers.id, ( cos( radians(latitude) ) * cos( radians( longitude ) ) ) AS distance"))
->havingRaw('distance < 200');
Run Code Online (Sandbox Code Playgroud)
我试图在关系(belongsTo)经销商的别名"距离"上使用havingRaw.但失败了一个错误:
未找到列:1054'having子句'中的未知列'距离'
UPDATE
当我将paginate函数添加到上述查询中时,实际上会出现问题.
$vehicle = Vehicle::join('dealers', 'vehicles.dealer_id', '=', 'dealers.id')
->select(DB::raw("dealers.id, ( cos( radians(latitude) ) * cos( radians( longitude ) ) ) AS distance"))
->havingRaw('distance < 200');
$result = $vehicle->paginate(15);
Run Code Online (Sandbox Code Playgroud)
如果你使用paginate()你的查询,laravel 将尝试执行以下 SQL 代码来计算可能匹配的总数:
select count(*) as aggregate
from `vehicles` inner join `dealers`
on `vehicles`.`dealer_id` = `dealers`.`id`
having distance < 200
Run Code Online (Sandbox Code Playgroud)
如您所见,distance此查询中没有这样的列或别名。
我原始答案中的选项 2也将解决该问题。
这似乎是一个 MySQL 严格模式问题。如果您使用 laravel 5.3 严格模式默认启用。您有两个选择:
选项 1:禁用 MySQL 的严格模式 config/database.php
...
'mysql' => [
...
'strict' => false,
...
],
...
Run Code Online (Sandbox Code Playgroud)
选项 2:使用 WHERE 条件
Vehicle::join('dealers', 'vehicles.dealer_id', '=', 'dealers.id')
->select(DB::raw("dealers.id, ( cos( radians(latitude) ) * cos( radians( longitude ) ) ) AS distance"))
->whereRaw('cos( radians(latitude) ) * cos( radians( longitude ) ) < 200');
Run Code Online (Sandbox Code Playgroud)
文档:
MySQL 对标准 SQL 的扩展允许在 HAVING 子句中引用选择列表中的别名表达式。启用 ONLY_FULL_GROUP_BY 会禁用此扩展,因此需要使用非别名表达式编写 HAVING 子句。
服务器 SQL 模式 - ONLY_FULL_GROUP_BY
mai*_*o84 -1
我所做的事情似乎与您尝试做的事情类似:
public function scopeNearest($query, Geo $geo, $miles = 25)
{
return $query
->select(DB::raw("*, ( 3959 * acos( cos( radians({$geo->lat}) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians({$geo->lng}) ) + sin( radians({$geo->lat}) ) * sin( radians( lat ) ) ) ) AS distance"))
->groupBy('id')
->having('distance', '<', $miles)
->orderBy('distance');
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,我有一个单独的模型,用于处理纬度和经度坐标以及名为 的地址信息Geo。您可能不需要这种级别的分离,因此您可以重构为如下所示:
public function scopeNearest($query, $lat, $lng, $miles = 25)
{
return $query
->select(DB::raw("*, ( 3959 * acos( cos( radians({$lat}) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians({$lng}) ) + sin( radians({$lat}) ) * sin( radians( latitude ) ) ) ) AS distance"))
->groupBy('id')
->having('distance', '<', $miles)
->orderBy('distance');
}
Run Code Online (Sandbox Code Playgroud)
请记住,为了计算距离,您需要两个点。该模型将能够通过使用自己的列latitude和longitude作为参数提供给范围查询的纬度和经度来检查两点之间的距离。
您可以将其放入您的车辆模型中并像这样调用:
Vehicle::nearest($latitude, $longitude, 200);
Run Code Online (Sandbox Code Playgroud)
这尚未针对您的用例进行测试,因此我不能保证它可以开箱即用,但希望它能为您指明正确的方向。
| 归档时间: |
|
| 查看次数: |
2799 次 |
| 最近记录: |