#やりかた
例えば棚卸システムを作るにあたって、以下のように3つのテーブルを作ったとする。
・stocks(在庫リスト)
・purchases(仕入リスト)
・materials(素材の基本情報をまとめたリスト)
※stocksにはpurchase_id
が、purchasesにはmaterial_id
がそれぞれ設定されている。
※materialsは材料を仕入れたときに材料名、仕入値、サイズなどが格納されている。
これをstocks -> purchases -> materials
の順番でjoinしたい。
たとえstocksの方にmaterial_idが設定されていても、やることは一緒。
// (namespaceやuseは省略)
// 2つのテーブルを普通にjoinする方法
$stocks = Stock::join('purchases', 'stocks.purchase_id', '=', 'purchases.id')->get();
// 3つ以上の複数テーブルをjoinする方法
$stocks = Stock::join('purchases', 'stocks.purchase_id', '=', 'purchases.id')
->join('materials', 'purchases.material_id', '=', 'materials.id')
->get();
これでdd($stocks);
すると1つのテーブルから取得してきたように、複数のテーブルがまとまって確認できる。
#joinとwhereなどを組み合わせる場合
普通にwhereやoderByを行う場合、以下のように記述する。
$stocks = Stock::where('カラム名', '条件の値')->get();
$stocks = Stock::orderBy('カラム名', 'desc')->get();
これはテーブルが1つだけなら問題ないが、複数テーブルを使う記述をする場合は、以下のように記述しないと、エラーの原因になる。
例えエラーにならなかったとしても、可読性が悪い。
$stocks = Stock::where('テーブル名.カラム名', '条件の値')->get();
$stocks = Stock::orderBy('テーブル名.カラム名', 'desc')->get();
#以上を踏まえて、以下の条件でjoinする場合の記述方法
・stocks
のdisplay
に0
が格納されているレコードのみ取得する。
・stocksにはpurchase_id
が、purchasesにはmaterial_id
がそれぞれ設定されている。
・stocks -> purchases -> materials
の順番にjoinする。
・materials
のmaterial_id(材料名)
で昇順にソートする。
$stocks = Stock::where('stocks.display',0)
->join('purchases', 'stocks.purchase_id', '=', 'purchases.id')
->join('materials', 'purchases.material_id', '=', 'materials.id')
->get();
#joinの条件にwhereなどを追加する場合の記述方法
上記のstocksとpurchasesをjoinする際に、purchasesのカラム名: test_clmが(int)99以上のレコードのみ
といいう条件を加える場合は以下のように記述する。
$stocks = Stock::where('stocks.display',0)
->leftJoin('purchases', function($join){
$join->on('stocks.purchase_id', '=', 'purchases.id')
->where('purchases.test_clm', '<=', 99);
})
->join('materials', 'purchases.material_id', '=', 'materials.id')
->get();
以上!
これで複数テーブルをjoinする基本はOKかな?(たぶん)