Laravel中获取各商品最新价格并筛选价格区间的查询方法
解决方案:Laravel 获取商品最新价格并筛选价格区间
你的现有代码存在两个核心问题:
whereHas仅用于判断商品是否存在符合条件的价格记录,但没有获取每个商品最新价格的逻辑;- 直接在关联查询里
groupBy('product_id')无法确保拿到的是该商品的最新价格记录。
下面提供两种可靠的实现方式:
方式一:子查询筛选最新价格记录
先通过子查询找出每个商品的最新价格ID,再关联查询筛选价格区间:
$minPrice = 0; $maxPrice = 50000; $products = Product::select('products.*', 'prices.amount as latest_price') ->joinSub( // 子查询:获取每个product_id对应的最新价格记录ID Price::select('product_id', DB::raw('MAX(id) as latest_price_id')) ->groupBy('product_id'), 'latest_prices', function ($join) { $join->on('products.id', '=', 'latest_prices.product_id'); } ) ->join('prices', 'prices.id', '=', 'latest_prices.latest_price_id') ->whereBetween('prices.amount', [$minPrice, $maxPrice]) ->get();
方式二:使用窗口函数(Laravel 8+ 支持)
通过 ROW_NUMBER() 窗口函数给每个商品的价格记录排序,取排序为1的最新记录,再筛选价格区间:
$minPrice = 0; $maxPrice = 50000; $products = Product::select('products.*', 'prices.amount as latest_price') ->join( DB::raw('( SELECT *, ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY created_at DESC) as rn FROM prices ) as latest_prices'), function ($join) { $join->on('products.id', '=', 'latest_prices.product_id') ->where('latest_prices.rn', 1); } ) ->whereBetween('latest_prices.amount', [$minPrice, $maxPrice]) ->get();
说明
- 两种方式都能确保拿到每个商品的最新价格(默认按价格记录的
id或created_at倒序判断最新,可根据你的实际字段调整排序条件); - 最终结果会包含商品信息和对应的最新价格
latest_price; - 如果你只需要商品模型数据,不需要价格字段,可以去掉
select里的prices.amount as latest_price,并调整关联逻辑。
内容的提问来源于stack exchange,提问作者Siavash01
相关产品推荐
相关产品推荐

