2017-03-27 106 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