You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中获取各商品最新价格并筛选价格区间的查询方法

解决方案:Laravel 获取商品最新价格并筛选价格区间

你的现有代码存在两个核心问题:

  1. whereHas 仅用于判断商品是否存在符合条件的价格记录,但没有获取每个商品最新价格的逻辑;
  2. 直接在关联查询里 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 23:46:01