なにがやりたかったか
aというテーブルとbというテーブルがある。
この2つをJOINにて結合し表示をしたかったが、このとき2つの列を使用し結合しなければ行けない場合がでてきた。
実現したいクエリとしては
SELECT *
FROM a
JOIN b ON a.id = b.a_id AND a.type = b.type
こんな感じ。
これをLaravelのクエリビルダにて実現したかった。
最初に試したコード
$query = DB::table('a')
->join('b', function ($join) {
$join->on('a.id', '=', 'b.a_id')->where('a.type', '=', 'b.type');
})
これを実行しクエリを確認したところ以下になっていた。
SELECT *
FROM a
JOIN b ON a.id = b.a_id AND a.type = 'b.type'
なぜかb.typeが文字列として実行されてしまう。
そしてreadoubleなどを見るとON条件が複数の場合の記述が書いていない。
orOnの記述はあるが、andOnがやりたいので、試しにandOnなどを試してみるがそんなメソッドはないと怒られる。
参考 : https://readouble.com/laravel/8.x/ja/queries.html
解決したコード
$query = DB::table('a')
->join('b', function ($join) {
$join->on('a.id', '=', 'b.a_id')->on('a.type', '=', 'b.type');
})
これを使用したコードにより解決がされた。
で、これをどこから見つけたかというと
Add an "on" clause to the join.
On clauses can be chained, e.g.
$join->on('contacts.user_id', '=', 'users.id') ->on('contacts.info_id', '=', 'info.id')
will produce the following SQL:
on contacts.user_id = users.id and contacts.info_id = info.id
参考 : https://laravel.com/api/5.5/Illuminate/Database/Query/JoinClause.html#method_on:~:text=%24join%2D%3Eon(%27contacts.user_id%27%2C%20%27%3D%27%2C%20%27users.id%27)%20%2D%3Eon(%27contacts.info_id%27%2C%20%27%3D%27%2C%20%27info.id%27)
と書いてあった。
readoubleに書いてなくてパニクったがこういうときはリファレンスがいいわね。
実行環境などはLaravel5以下で試しているがクエリビルダの話なので、多分Laravel8とかでも大丈夫ではあろう・・・