Laravel Eloquentからサブクエリでjoinするのに苦戦した

Larave Eloquentからデータベース操作するとき

  • サブクエリでテーブル結合したい
  • 例えば INNER JOINとかしたり、
  • あるいは LEFT JOINとかしたい

こういう場面に遭遇しました。

MySQLでのJOIN文・サブクエリなどを生で書くって方法もあるんですが、それはセキュリティ的に危険すぎますよね。

そこでLaravel Eloquentでサブクエリを使ってテーブル同士を結合(JOIN)する方法をまとめます。忘れがちなので自分用メモ

MySQLでのサブクエリ+JOIN文のテーブル結合の例

まずはLaravelを使わない場合の話から

こういう構成のテーブルがあるとします。

▼ 1つめ : usersテーブル

id name
1 チャーリー
2 サリー
3 ルーシー
4 ライナス
5 ビッグペン

▼ 2つめ : user_hobbiesテーブル

id user_id hobby
1 1 野球観戦
2 2 プラモデル作り
3 2 神社仏閣めぐり
4 5 ソシャゲ課金
5 3 ボルダリング
6 1 バドミントン
7 4 バイク
8 5 ハンドメイド
9 3 バイク
10 4 野球観戦

1つめのusersテーブルのidカラムがユーザーID、そして2つめのusers_hobbiesテーブルのuser_idカラムがユーザーIDと対応してます。

この2つをusersテーブルに対してusers_hobbiesテーブルを結合させたい場合、次のようなJOIN文を使うことで結合可能です。

▼ このようなSQL例

このSQLにおいては sub1.id = sub2.post_id  において結合の共通カラムを指定してます。結合する際はON句に結合条件が必須。(ちなみにFROM句の後のサブクエリは複雑なクエリを想定)

それから分かりやすいようにサブクエリに別名sub1、sub2を付けてます。こういうサブクエリとJOIN文の組み合わせでテーブル結合が可能です。

これをLaravelでやるのに苦戦した・・・

Laravelでサブクエリ+JOIN文でテーブル結合

このやり方が分からなくて困りました。

でも公式リファレンスでも説明されてます。

▼ 上級のJOIN文について

さらに上級なJOIN節を指定することもできます。そのためにはjoinメソッドの第2引数に「クロージャ」を指定します。その「クロージャ」はJOIN節に制約を指定できるようにするJoinClauseオブジェクトを受け取ります。

引用元 : https://readouble.com/laravel/5.6/ja/queries.html

これを使えば複雑なテーブル結合も楽々です。

 

実際に先ほどの例でコードを書いてみました。

▼ usersテーブルとusers_hobbiesテーブル結合

このようにjoinメソッドの第1引数に 'user_hobbies as sub2'  みたいな結合先テーブル、第2引数に function ($join) {...}  のように結合用のクロージャを渡して共通カラムで結合させるだけです。

ちなみにControllerとかModelは省略してます。そこはLaravelの基礎中の基礎なので、分からないならググってください。

このコードのように joinメソッドの第2引数に結合させるためのコールバック巻数を渡すのがキモです。他は何も難しくありません。

ちなみにjoinメソッドではWHEER句の指定も可能

もちろんWHERE句なども追加で指定可能です。

▼ こういったWHERE句の指定もできる

これはサブクエリ内でWHERE句指定と同じですね。

こういった複雑なサブクエリも簡潔に書けるのがLaravelの利点の1つなのかも。joinメソッドを使えば多重のテーブル結合も簡単です。

以上、Laravel Eloquentでのサブクエリの結合でした。

もし間違いがあればご指摘ください。ではまた

Shareこの記事をシェアしよう!

Commentsこの記事についたコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください