8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Eloquentで複数テーブルをjoinする

Last updated at Posted at 2021-08-23

#やりかた
例えば棚卸システムを作るにあたって、以下のように3つのテーブルを作ったとする。
・stocks(在庫リスト)
・purchases(仕入リスト)
・materials(素材の基本情報をまとめたリスト)
stocksにはpurchase_idが、purchasesにはmaterial_idがそれぞれ設定されている。
※materialsは材料を仕入れたときに材料名、仕入値、サイズなどが格納されている。

これをstocks -> purchases -> materialsの順番でjoinしたい。
たとえstocksの方にmaterial_idが設定されていても、やることは一緒。

StockController.php
// (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を行う場合、以下のように記述する。

StockController.php
$stocks = Stock::where('カラム名', '条件の値')->get();
$stocks = Stock::orderBy('カラム名', 'desc')->get();

これはテーブルが1つだけなら問題ないが、複数テーブルを使う記述をする場合は、以下のように記述しないと、エラーの原因になる。
例えエラーにならなかったとしても、可読性が悪い。

StockController.php
$stocks = Stock::where('テーブル名.カラム名', '条件の値')->get();
$stocks = Stock::orderBy('テーブル名.カラム名', 'desc')->get();

#以上を踏まえて、以下の条件でjoinする場合の記述方法

stocksdisplay0が格納されているレコードのみ取得する。
stocksにはpurchase_idが、purchasesにはmaterial_idがそれぞれ設定されている。
stocks -> purchases -> materialsの順番にjoinする。
materialsmaterial_id(材料名)で昇順にソートする。

StockController.php
$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以上のレコードのみといいう条件を加える場合は以下のように記述する。

StockController.php
$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かな?(たぶん)

8
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?