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

Laravel中使用with()子查询时如何关联主表字段筛选?

你遇到的问题是在Laravel嵌套预加载时,无法用主表group_products的id字段作为子查询的筛选条件——直接写'group_products.id'会被当成字符串值,而非字段引用,同时预加载的独立查询也没有关联主表,导致条件失效。

方案一:预加载时用whereExists关联主表字段

通过子查询关联主表与嵌套的order_items表,确保筛选出与当前group_product匹配的订单项:

use Illuminate\Support\Facades\DB;

$groups = GroupProduct::where('status', 1)
    ->with(['groupProductProduct.product' => function ($query) use ($id) {
        $query->where('products.situation', 1)
            ->with(['items.orderitems' => function($query2) use ($id) {
                $query2->where('order_items.order_id', $id)
                    ->whereExists(function ($subQuery) {
                        // 通过中间关联表将order_items与当前group_product关联
                        $subQuery->select(DB::raw(1))
                            ->from('group_products_products')
                            ->join('products', 'products.id', '=', 'group_products_products.product_id')
                            ->join('items', 'items.product_id', '=', 'products.id')
                            ->whereColumn('items.id', 'order_items.item_id')
                            ->whereColumn('group_products_products.group_product_id', 'group_products.id');
                    })
                    ->with('subitems');
            }]);
    }])
    ->get();

方案二:使用join直接关联所有表(更直观)

通过join将所有关联表串联,直接在查询中比较字段,确保筛选逻辑生效,同时预加载所需关联数据:

$groups = GroupProduct::select('group_products.*')
    ->where('group_products.status', 1)
    // 关联所有层级的表
    ->join('group_products_products', 'group_products_products.group_product_id', '=', 'group_products.id')
    ->join('products', 'products.id', '=', 'group_products_products.product_id')
    ->join('items', 'items.product_id', '=', 'products.id')
    ->join('order_items', 'order_items.item_id', '=', 'items.id')
    // 添加筛选条件
    ->where('products.situation', 1)
    ->where('order_items.order_id', $id)
    ->whereColumn('order_items.group_product_id', '=', 'group_products.id')
    // 预加载完整关联链
    ->with(['groupProductProduct.product.items.orderitems.subitems'])
    // 去重避免重复的group_product记录
    ->distinct()
    ->get();

关键说明

  • 当需要比较两个数据库字段而非字段与固定值时,必须用whereColumn替代where,否则Laravel会把字段名当作字符串值处理。
  • 嵌套预加载的查询是独立执行的,无法直接访问主表字段,必须通过子查询(whereExists)或join的方式建立关联。

内容的提问来源于stack exchange,提问作者gobs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:52:51