Laravel关联查询问题:如何获取单个市场下每个商品的最新价格?
解决Laravel关联中获取每个商品最新价格的问题
嘿,我明白你的困扰了!你现在的prices关联用了groupBy('item'),但拿不到每个商品的最新价格,核心原因是**groupBy会先把相同item的记录分组,这时候orderByDesc是对分组后的结果排序,而不是在每组内部筛选最新的那条**,所以你拿到的其实是每组里的第一条(通常是最早的或者随机的),不是你要的最新数据。
下面给你几个靠谱的解决方案,按需选择:
方案一:用子查询筛选每个商品的最新记录(推荐)
这种方法兼容性最好,不管数据库配置如何都能稳定工作。修改你的Market模型关联方法,或者新增一个latestPrices方法:
use Illuminate\Support\Facades\DB; public function latestPrices() { return $this->hasMany(MarketPrices::class, self::IDMarket) ->whereIn('id', function ($query) { // 子查询:找到每个item对应的最新记录的id(假设id是自增主键,用它判断新旧) $query->select(DB::raw('MAX(id)')) ->from('market_prices') // 替换成你的MarketPrices表的实际表名 ->whereColumn('market_id', 'markets.id') // 关联Market模型的主键和外键 ->groupBy('item'); }); }
如果你的表是用created_at或updated_at来判断最新,而不是id,把子查询改成这样:
$query->select('id') ->from('market_prices') ->whereColumn('market_id', 'markets.id') ->orderBy('created_at', 'desc') ->groupBy('item');
使用的时候直接调用这个关联就行:
// 获取单个market的所有商品最新价格 $market = Market::find($yourMarketId); $latestItemPrices = $market->latestPrices; // 预加载多个market的最新价格 $markets = Market::with('latestPrices')->get();
方案二:先排序再分组(仅适合特定数据库配置)
如果你的MySQL关闭了ONLY_FULL_GROUP_BY模式,可以尝试先按时间降序排序,再分组(因为分组会保留排序后的第一条记录,也就是最新的):
public function prices() { return $this->hasMany(MarketPrices::class, self::IDMarket) ->orderByDesc('created_at') // 先按时间降序 ->groupBy('item'); // 再分组,保留每组第一条(最新的) }
⚠️ 注意:这个方法依赖数据库配置,开启ONLY_FULL_GROUP_BY后会直接报错,所以不推荐在生产环境使用,仅作为临时方案。
为什么原来的方法不生效?
再啰嗦一句:你之前加的orderByDesc是对分组后的集合排序,而不是对分组前的每条记录排序。比如先把所有item=A的记录分成一组,item=B的分成一组,再把A、B组按时间排序,但每组内部还是原来的第一条记录,不是最新的,所以完全达不到你要的效果。
内容的提问来源于stack exchange,提问作者Cleoh
相关产品推荐
相关产品推荐

