Laravel - Eloquent - 渴望加载 - 限制/选择/分组

时间:2017-03-27 04:30:37

标签: laravel join eloquent constraints eager-loading

我发现Eloquent的加入逻辑比典型的准备语句复杂得多(读起来我讨厌它)。

有人可以帮我把以下查询翻译成一个明智的,强烈的完全急切加载的查询吗?

SELECT  C.id,
        C.seo_alias
FROM store_variants AS A 
LEFT JOIN variants  AS B ON B.id = A.id_variant
LEFT JOIN products  AS C ON C.id = B.id_product
LEFT JOIN stores    AS D ON D.id = A.id_store
WHERE D.id = 123
AND A.isActive > 0
GROUP BY C.id;

一种产品 - 许多变种

一个变种 - 许多商店

一个store_variant - 一个商店

模型是storeVariantModel,variantModel,productModel,storeModel。有数百万行。

我看到它的方式,这个查询包含过滤的选择,连接,分组和约束,所以它涵盖了我每天遇到的大多数操作,所以如果有人能解决这个问题,你真诚的感谢。

谢谢

编辑:使用Laravel 5.2

编辑:解决方案#2:

感谢@Balraj的帮助,这基本上是我被迫使用的最终解决方案:

storeVariantModel::
    join(   'variants', 'variants.id_variant',  '=', 'store_variants.id')
    ->join( 'products', 'products.id',          '=', 'variants.id_product')
    ->join( 'stores',   'stores.id',            '=', 'store_variants.id_store')
    ->with([
        'variantModel.storeVariantModel.storeModel',
        'variantModel.productModel'
    ])
    ->select('variants.*')
    ->where('stores.id','=',123)
    ->where('store_variants.isActive','>',0)
    ->get();

修改:我不再使用'GROUP BY'

优点:我得到的模型有关系,对中间表的约束过滤数据,而不是只加急加载任何匹配约束的数据

缺点:语法是球,我基本上是两次调用连接,我不再为一组有限的列做选择

2 个答案:

答案 0 :(得分:1)

试试这个,

storeVariantModel::join('variants.id_variant','=','store_variants.id')
          ->join('products','products.id','=','variants.id_product')
          ->join('stores','stores.id','=','store_variants.id_store')
          ->select(['products.id','products.seo_alias'])
          ->where('stores.id','=',123)
          ->where('store_variants.isActive','>',0)
          ->groupby('products.id')
          ->get();

更新答案

没有groupby的雄辩:

In productModel:
public function variants(){
    return $this->hasMany(variantModel::class,'id_product','id');
}

In variantModel:
public function store_variants(){
    return $this->hasMany(storeVariantModel::class,'id_variant','id);
}

In storeVariantModel:
public function stores(){
    return $this->hasOne(storeModel::class,'id','id_store');
}



productModel::with(['variants.store_variants.stores' => function($q){
    $q->where('id','=',123);
}])->whereHas('variants.store_variants', function($q){
    $q->where('isActive','>',0);
})->get();

答案 1 :(得分:0)

按照你的描述,C有很多B,B有很多A,D有很多A.

你可以用这样的约束来加载它们

$result = CModel::with(['BRelationship' => function ($query) {
    $query->with(['ARelationship' => function ($sub1) {
        $sub1->with(['DRelationship' => function($sub2) {
            $sub3->where('id', '123);
        }]);
    }])->where('condition') //to add extra condition if you want
    ->groupBy('column'); //if you want to group by in ARelationship
}])->get();

您可以将其读作C,其中B带有A和D.

我还没有测试过这段代码。另外不要忘记正确定义关系。