Laravel Eloquent嵌套关联的withExists/withCount使用问题(多对多与一对多)
Laravel 关联查询:判断产品是否存在价格
模型关联定义
- Product.php:
public function skus() { return $this->belongsToMany(Sku::class); }
- Sku.php:
public function prices() { return $this->hasMany(Price::class); }
需求
要给Product模型的查询结果添加一个属性,用来标记该产品是否至少拥有一个价格(或者极端情况,统计价格的总数量)。
试过以下方法但无效:
Product::withExists('sku.prices') or Product::withCount('sku.prices')
了解staudenmeir/belongs-to-through扩展包,但更倾向于用原生复杂查询一次性解决问题。
更新说明
已经写出了实现需求的SQL语句,但不知道如何在Laravel中对应实现:
SELECT *, EXISTS (SELECT * FROM prices INNER JOIN skus ON prices.sku_id = skus.id INNER JOIN product_sku ON skus.id = product_sku.sku_id WHERE products.id = product_sku.product_id ) AS prices_exists FROM products
Laravel 实现方案
1. 实现 EXISTS 判断(与自定义SQL逻辑完全一致)
直接用addSelect结合子查询即可实现,返回prices_exists字段:
$products = Product::addSelect([ 'prices_exists' => function ($query) { $query->selectRaw('1') ->from('prices') ->join('skus', 'prices.sku_id', '=', 'skus.id') ->join('product_sku', 'skus.id', '=', 'product_sku.sku_id') ->whereColumn('product_sku.product_id', 'products.id') ->limit(1); } ])->get();
查询结果里的prices_exists字段会是1(存在价格)或null(不存在),可直接用于判断。
2. 统计价格总数量
如果需要统计产品关联的所有价格数量,用类似的子查询写法:
$products = Product::addSelect([ 'prices_count' => function ($query) { $query->selectRaw('COUNT(prices.id)') ->from('prices') ->join('skus', 'prices.sku_id', '=', 'skus.id') ->join('product_sku', 'skus.id', '=', 'product_sku.sku_id') ->whereColumn('product_sku.product_id', 'products.id'); } ])->get();
3. 简化的多层关联判断写法
如果想尝试用withExists的多层关联写法,可以给关联添加闭包(部分Laravel版本需注意关联层级兼容性):
$products = Product::withExists([ 'skus.prices' => function ($query) { $query->selectRaw('1'); } ])->get();
若此写法无效,优先使用第一种子查询方式,完全匹配自定义SQL逻辑。
内容的提问来源于stack exchange,提问作者Alexander Khokhanov
相关产品推荐
相关产品推荐

