Inv*_*tax 6 mysql laravel eloquent
我正在使用Laravel构建搜索列表应用程序; 该应用程序需要按距离(我已经建立)搜索企业,并包括对企业的最新订阅(如果有的话),以便我可以通过它然后距离来订购.
这里的两个模型是商业和订阅.一个企业可以拥有许多订阅(虽然只会有一个活跃的订阅).
调节器
$businesses = Business::distance($place['lat'], $place['lng'], $request->distance)
->ofShopType($request->shop_type)
->uptoBudget($request->price)
->leftJoin('subscriptions', function($join) {
$join->on('businesses.id', '=', 'subscriptions.business_id')
->orderBy('subscriptions.created_at', 'desc');
});
return $businesses = $businesses->get();
Run Code Online (Sandbox Code Playgroud)
商业模式
public function scopeDistance($query,$from_latitude,$from_longitude,$distance)
{
$raw = \DB::raw('ROUND ( ( 3959 * acos( cos( radians('.$from_latitude.') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('.$from_longitude.') ) + sin( radians('.$from_latitude.') ) * sin( radians( latitude ) ) ) ), 1 ) AS distance');
return $query->select('*')->addSelect($raw)
->orderBy( 'distance', 'ASC' )
->groupBy('businesses.id')
->having('distance', '<=', $distance);
}
Run Code Online (Sandbox Code Playgroud)
所以我遇到的困难是这个business.id
领域被覆盖了subscription.id
.我已经做了一些搜索,并已阅读包括->select('businesses.*')
在leftJoin
应解决此问题之前,但通过这样做我得到以下错误:
SQLSTATE[42S22]: Column not found: 1054 Unknown column
'business.distance' in 'having clause'
(SQL: select `businesses`.*
from `businesses`
left join `subscriptions`
on `businesses`.`id` = `subscriptions`.`business_id`
where `shop_type_id` = 1
and `min_cost` <= 100
group by `distance`, `businesses`.`id`
having `distance` <= 50
order by `distance` asc)
Run Code Online (Sandbox Code Playgroud)
第二个问题是左连接似乎得到了第一条记录,我想得到最新的记录(by created_at
).您可以看到orderBy
我的控制器中已经有一条线,但这没有任何影响,因为我可以看到它仍然返回较旧的记录,即使有更新的记录可用.
如果您->select('businesses.*')
在控制器中使用,您将覆盖您的选择scopeDistance()
。您应该在范围函数中使用表别名。我还会groupBy()
从范围函数中删除,因为它在那里没有意义。最好orderBy()
也删除,因为以后您无法(轻松)覆盖它。
public function scopeDistance($query,$from_latitude,$from_longitude,$distance)
{
$raw = \DB::raw('ROUND ( ( 3959 * acos( cos( radians('.$from_latitude.') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('.$from_longitude.') ) + sin( radians('.$from_latitude.') ) * sin( radians( latitude ) ) ) ), 1 ) AS distance');
return $query->select('businesses.*')->addSelect($raw)
->having('distance', '<=', $distance);
}
Run Code Online (Sandbox Code Playgroud)
如果您想按上次订阅创建时间对结果进行排序,则需要使用聚合函数进行排序。在你的情况下应该是ORDER BY MAX(subscriptions.created_at) DESC
。这也是 GROUP BY 的正确位置business.id
。ORDER BY
在 JOIN 子句中使用它没有意义。我希望得到一个异常,因为我不知道如何将其转换为有效的 SQL 表达式。但 Laravel 似乎只是忽略了它。所以控制器中的代码可能是:
$businesses = Business::distance($place['lat'], $place['lng'], $request->distance)
->ofShopType($request->shop_type)
->uptoBudget($request->price)
->leftJoin('subscriptions', 'businesses.id', '=', 'subscriptions.business_id')
->groupBy('business.id')
->orderByRaw('max(subscriptions.created_at) DESC')
->orderBy('distance', 'ASC');
return $businesses->get();
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
563 次 |
最近记录: |