Laravel leftJoin 只加入右表的最后一条记录并按它排序
Posted
技术标签:
【中文标题】Laravel leftJoin 只加入右表的最后一条记录并按它排序【英文标题】:Laravel leftJoin only last record of right table and order by it 【发布时间】:2021-05-03 17:31:00 【问题描述】:我有两张桌子。 1) 产品 2) 价格
-------------------------
- products -
-------------------------
- id | int -
- name | varchar -
- created_at | datetime -
- updated_at | datetime -
-------------------------
----------------------------
- prices -
----------------------------
- id | int -
- product_id | int -
- sale_price | int -
- regular_price | int -
- created_at | datetime -
- updated_at | datetime -
-----------------------------
我想搜索产品并从价格表中获取每种产品的最后价格。我用这个:
class Product extends Model
public function lastPrice()
return $this->hasOne(Price::class)->orderBy('id', 'DESC');
我使用以下命令获取具有最新价格的产品列表:
$products=Product::with('lastPrice')->paginate(9);
我的问题是:我想按最高/最低价格订购结果。我将如何做到这一点?
【问题讨论】:
这能回答你的问题吗? Laravel leftJoin only last record of right table 【参考方案1】:我相信使用laravel 6 或更高版本您可以在addSelect()
子句中使用相关子查询作为
Product::addSelect(['latest_price' =>
Price::select('price')
->whereColumn('product_id', 'products.id')
->orderBy('id', 'desc')
->limit(1)
])->orderBy('latest_price','desc')
->paginate(9);
因此,我们将从上面获取产品数据以及数据库中的最新价格列,以便您可以在latest_price
上应用排序
编辑如果您有有限的列可供选择,例如 sale_price
,您可以添加另一个子查询,但如果您想从价格表中选择整行,请查看另一种使用 join/exists 的方法
Product::addSelect(['sale_price' =>
Price::select('sale_price')
->whereColumn('product_id', 'products.id')
->orderBy('id', 'desc')
->limit(1),
'regular_price' =>
Price::select('regular_price')
->whereColumn('product_id', 'products.id')
->orderBy('id', 'desc')
->limit(1),
])->orderBy('sale_price','desc')
->orderBy('regular_price','desc')
->get();
【讨论】:
谢谢,M Khalid Junaid 给了我 1/2 的解决方案,但如果价格表有其他列(如 sale_price 和 regular_price),我怎样才能得到它们。按销售价格订购 我已经为您的问题更新了我的答案,并发布了另一个使用不同方法的答案【参考方案2】:您可以从价格表中选择最新行以及产品数据,我现在可以想到两种方法
// Approach 1
Product::join('prices as a', 'products.id', '=', 'a.product_id')
->leftJoin('prices as a1', function ($join)
$join->on('a.product_id', '=', 'a1.product_id')
->whereRaw(DB::raw('a.id < a1.id'));
)
->whereNull('a1.product_id')
->select('products.*', 'a.*')
->orderBy('sale_price','desc')
->orderBy('regular_price','desc')
->get();
// Approach 2 with whereExists
Product::join('prices as a', 'products.id', '=', 'a.product_id')
->whereExists(function ($query)
$query->select(DB::raw(1))
->from('prices as b')
->whereRaw(DB::raw('a.product_id = b.product_id'))
->havingRaw('max(b.id) = a.id');
)
->select('products.*', 'a.*')
->orderBy('sale_price','desc')
->orderBy('regular_price','desc')
->get();
【讨论】:
以上是关于Laravel leftJoin 只加入右表的最后一条记录并按它排序的主要内容,如果未能解决你的问题,请参考以下文章