laravel

Laravel8でjoin時のon句に複数条件を付ける場合の書き方を紹介【注意点あり】

団結

 

あなた
Laravel8でjoin時に、複数の条件をつけたいです。

どうしたらいいですか?

 

今回はこのような疑問に答えていきます。

 

結論:joinメソッドの引数にクロージャを渡す

 

結論から話すと、joinメソッドの引数にクロージャを渡せばOKです。

 

より高度なJOIN句を指定することもできます。そのためには、joinメソッドの2番目の引数にクロージャを渡します。クロージャはIlluminate\Database\Query\JoinClauseインスタンスを受け取ります。これにより、"join"句に制約を指定できます。

引用:公式ドキュメント

 

コード例を紹介

 

実現したいSQLが以下だとします。

 

SELECT 
    `users`.`name` AS `user_name`,
    `messages`.*
FROM
    `messages`
        INNER JOIN
    `users` ON `messages`.`user_id` = `users`.`id`
    AND   `messages`.`id` > '13'

 

この場合、laravel側のコードは次のようになります。

where()の部分で、2つ目のON句の条件を指定しています。

 

DB::table('messages')
->join('users', function ($join) {
                $join->on('messages.user_id', '=', 'users.id')
                    ->where('messages.id', '>', 13);
            })
->select('users.name as user_name', 'messages.*')->get();

 

ちなみに、on句で「or」を使いたい場合は

->orOn('messages.pro_id', '=', 'users.id');

のように書いてあげればOKです。

 

【補足】

処理実行時に、SQLを確認できるように、デバッグモードをONにしておくといいです。Laravel8.Xでデバックモードを有効&デバッグバーを表示する方法【できない場合の解決方法も記載】で方法を紹介しています。

 

デバッグモード時のSQL
こんな感じで、実行されているSQLを確認できます

【注意点】ON句の条件に、変数を使うことはできない

 

本題に戻ります。

実は、先程のjoinメソッドを使った方法では、ON句で変数を使うことができません。

コード例は以下です。

 

//これだと失敗します
DB::table('messages')
->join('users', function ($join,$num) {
        $join->on('messages.user_id', '=', 'users.id')
         ->where('messages.id', '>', $num); //ここで$numは使えません
    })
->select('users.name as user_name', 'messages.*')->get();

 

じゃあ変数を使いたい場合は、どうすればいいかですが、結論から話すとSQLを直書きするといいです。

次のように書いてみましょう。

 

DB::select('SELECT `users`.`name` AS `user_name`, `messages`.* FROM `messages` INNER JOIN `users` ON `messages`.`user_id` = `users`.`id` AND `messages`.`id` > ?' , [$num]);

 

こうすることで、変数$numもon句で使用可能になります。

 

-laravel

© 2021 エンジニアてんし君ブログ