我需要抓住那些与经销商关系密切的车辆。距离< 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');
我正试图在别名&#39;距离&#39;上使用havingRaw。来自关系(belongsTo)经销商。但失败了,错误:
未找到列:1054未知列&#39;距离&#39;在&#39;有条款&#39;
更新
当我将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);
答案 0 :(得分:4)
如果对查询使用 program Project1;
uses
Vcl.Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
var
MainForm: TForm1;
begin
Application.Initialize;
Application.MainFormOnTaskbar := True;
if Login then
begin
Application.CreateForm(TForm1, Form1);
Application.Run;
end
else Application.Terminate;
end.
laravel将尝试执行以下SQL代码来计算可能匹配的总数:
paginate()
如您所见,此查询中没有此类列或别名select count(*) as aggregate
from `vehicles` inner join `dealers`
on `vehicles`.`dealer_id` = `dealers`.`id`
having distance < 200
。
选项2 也将解决这个问题。
这种接缝是MySQL严格模式的问题。如果使用laravel 5.3默认情况下启用严格模式。您有两种选择:
选项1:在distance
config/database.php
选项2:使用WHERE condtition
...
'mysql' => [
...
'strict' => false,
...
],
...
文档:
标准SQL的MySQL扩展允许HAVING中的引用 选择列表中的别名表达式的子句。启用 ONLY_FULL_GROUP_BY禁用此扩展,因此需要HAVING 使用非混淆表达式编写的子句。
答案 1 :(得分:2)
答案已更新,对应更新的问题
问题在于查询构建器,因为在进行聚合调用时会丢弃所有选择(如count(*))。目前,make-do解决方案是手动构建paginator:
$query = Vehicle::join('dealers', 'vehicles.dealer_id', '=', 'dealers.id')
->select(DB::raw("dealers.id, ( cos( radians(latitude) ) * cos( radians( longitude ) ) ) AS distance"))
->having('distance', '<', '200');
$perPage = 10;
$curPage = \Illuminate\Pagination\Paginator::resolveCurrentPage();
$itemQuery = clone $query;
$items = $itemQuery->forPage($curPage, $perPage)->get();
$totalResult = $query->addSelect(DB::raw('count(*) as count'))->get();
$totalItems = $totalResult->first()->count;
$vehicles = new \Illuminate\Pagination\LengthAwarePaginator($items->all(), $totalItems, $perPage);
答案 2 :(得分:1)
having
和havingRaw
无法访问查询中生成的字段
从laravel docs看这个例子
您的查询必须像这样
Vehicle::join('dealers', 'vehicles.dealer_id', '=', 'dealers.id')
->select(DB::raw("dealers.id, ( cos( radians(latitude) ) * cos( radians( longitude ) ) ) AS distance"))
->havingRaw('(cos(radians(latitude)) * cos(radians(longitude))) < 200');
答案 3 :(得分:0)
我做的事情似乎与你要做的事情类似:
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');
}
在这个例子中,我有一个处理纬度和经度坐标的单独模型,以及名为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');
}
请记住,为了计算距离,您需要两点。该模型将能够使用自己的latitude
和longitude
列来检查两点之间的距离,并将作为参数提供给范围查询的纬度和经度。
你可以把它放在你的车型中,然后像这样打电话:
Vehicle::nearest($latitude, $longitude, 200);
这对于您的用例未经测试,因此我无法保证它能够开箱即用,但希望它能为您指明正确的方向。
答案 4 :(得分:0)
这应该有效:
Vehicle::join('dealers', 'vehicles.dealer_id', '=', 'dealers.id')
->select(DB::raw("dealers.id, ( cos( radians(latitude) ) * cos( radians( longitude ) ) ) AS distance")->havingRaw('distance < 200'));