LaravelのクエリビルダーでサブクエリにWhere句があったときにいろいろと調べましたのでまとめます。
こちら、ブログでも公開しております。
Where句のバインド値をマージしないとエラーになる
わざわざサブクエリにする必要はありませんが、確認のため以下のSQLで試してみたいと思います。
select * from (
select * from table1 where status = 'Success'
) as s1
left join (
select * from table2 where status = 'New'
) as s2 on s1.id = s2.relid
where t.id = 1
先にサブクエリを定義して、DB::raw()を使用してSQLを組み立てて行きます。
以下のコードで問題はないと思っていましたが、バインド値がないためエラーになってしまいました。
$subquery1 = \DB::table('table1')
->where('status', '=', 'Success');
$subquery2 = \DB::table('table2')
->where('status', '=', 'New');
$query = \DB::table(\DB::raw("({$subquery1->toSql()}) as s1"))
->leftjoin(\DB::raw("({$subquery2->toSql()}) as s2"), function($join){
$join->on('s1.id', '=','s2.relid');
})
->where('t.id', '=', 1);
$data = $query->get();
実際にmergeBindings()を使ってバインド値をマージします。
マージする順番も気をつける必要がありますので注意してください。
SQLの上から順番になるようにマージしていきます。
$subquery1 = \DB::table('table1')
->where('status', '=', 'Success');
$subquery2 = \DB::table('table2')
->where('status', '=', 'New');
$query = \DB::table(\DB::raw("({$subquery1->toSql()}) as s1"))
->leftjoin(\DB::raw("({$subquery2->toSql()}) as s2"), function($join){
$join->on('s1.id', '=','s2.relid');
})
->mergeBindings($subquery1)
->mergeBindings($subquery2)
->where('t.id', '=', 1);
$data = $query->get();
バインド値はgetBindings()で確認することができます。
$query->getBindings()