2017-03-27 67 views
1

我发现Eloquent的加入逻辑比典型的准备语句复杂得多(阅读我讨厌它)。Laravel - 雄辩 - 渴望加载 - 约束/选择/分组

有人可以帮我把下面的查询翻译成一个明智的雄辩的查询,这是整个急切加载?

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,产品型号,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'

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

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

+0

你能提供关于模型之间关系的细节吗?姓名,基数等 – fubar

+0

C有很多B,B有很多A,D有很多A – mils

+0

有什么名字?例如。 '$ store-> products' ... – fubar

回答

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(); 
+0

我需要使用雄辩,而不是查询生成器 – mils

+0

道歉,我以为你正在做一个DB ::调用,实际上你的代码返回一个模型,所以它是完全可用的,并且今天下午的事情,你的是唯一的代码,我可以开展工作,而且是唯一正在进行正确连接的人,而不是子查询。所以谢谢! – mils

+0

@mils我尝试使用急切的加载,但因为'groupBy'我不能做到这一点。所以,我认为这是解决问题的唯一方法。 –

0

按照你的描述,C的hasMany B,B的hasMany A,d的hasMany 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 with A with D.

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

+0

立即试用您的代码。 “with”条件加载相关的模型,但每次添加一个约束如“$ sub3-> where('id','123);”该模型没有被加载的热切负载。有任何想法吗? – mils

+0

您确定这只是拉着这个条件的行,或者只是急切地加载符合条件的行吗?你需要使用“whereHas”,在这种情况下,它仍然是渴望加载? – mils