Laravelのクエリビルダである程度データの取得ができるようになったけど、サブクエリの場合はどうやって書けばいいんだろう….
こんな疑問を解決します。
私が実務で解決するまでに時間かかったのはサブクエリのクエリビルダってどうやって書けばいいんだろう?でした。
結論toSql()を使って実装できたのでその方法を解説します。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
LaravelのクエリビルダをSQLに変換する
Laravelのクエリビルダは便利ですが、実務でサブクエリがあるSQLを扱う場面があり、サブクエリでクエリビルダを表すにはどうすればいいんだ??となりましたが、結論toSql()でできました。
例えば、
$query_1 = ….->toSql();
$query_2 = …->toSql();
DB::table(DB::raw(‘(‘.$query_1.’) AS a’))
みたいにできます。
クエリビルダでサブクエリを使うには、toSql()を使えばいいのですがそもそもtoSql()は、クエリビルダをSQLに変換してくれます。
例えば、以下のようなクエリビルダは、
public function findBookByCategoryId($categoryId)
{
return $this
->where('category_id', 1)
->toSql();
}
"select * from `books` where `category_id` = ?"
このようにtoSql()を用いるとSQLに変換されます。
ちなみに?にはsetBindingsを用いて値を安全に代入する必要があります。
サブクエリをクエリビルダで書く
toSql()でクエリビルダをSQLに変換できたら、あとは値を代入していくだけです。
一応構文としてはこんな感じ。
【代入するのが1つの場合】
$query_1 = ...->toSql();
DB::table(DB::raw('('.$query_1.') AS first'))
->setBindings([':最初の?' => ?に代入する値])
->get();
public function findBookByCategoryId($categoryId)
{
$query_1 = $this
->where('category_id', 1)
->toSql();
return DB::table(DB::raw('('.$query_1.') AS first'))
->setBindings([':category_id' => $categoryId])
->get();
}
【代入するのが2つの場合】
public function findBookByCategoryId($categoryId)
{
$query_1 = $this
->where([
['category_id', 1],
['book_name', '独習PHP'],
])
->toSql();
// $query_1の結果("select * from `books` where (`category_id` = ? and `book_name` = ?)")
// ?が2つになる。そのため、setBindingsに対応する値を順番に代入する必要がある。
return DB::table(DB::raw('('.$query_1.') AS first'))
->setBindings([
[':category_id' => $categoryId],
[':book_name' => '独習PHP'],
])
->get();
}
このようにtoSqlを使ってサブクエリでもクエリビルダを実行できます。
【まとめ】Laravelクエリビルダでサブクエリを使ってデータを取得する方法
今回はLaravelでサブクエリでもクエリビルダ使えるよって方法を解説しました。
toSqlを使ってSQLに変換し、.$query_1.のようにSQLを代入すればいいんでしたね。
このブログでは他にも実務に役立つLaravelの記事を書いているのでぜひ参考にしてください。
休日で空いた時間の暇つぶしを探せるアプリを公開しています。
コメント