Elegantly select data from subqueries using the Laravel query builder
In a recent project, you used Eloquent ORM to retrieve data from a database. One of the requirements is to use a subquery to count the number of records in a specific column. Here is the SQL query you are trying to execute:
<code class="language-sql">SELECT COUNT(*) FROM (SELECT * FROM abc GROUP BY col1) AS a;</code>
Your first attempt at using the from()
and groupBy()
methods of the Abc model:
<code class="language-php">$sql = Abc::from('abc AS a')->groupBy('col1')->toSql(); $num = Abc::from(\DB::raw($sql))->count(); print $num;</code>
However, you are looking for a more elegant solution.
Complete solution
The Laravel query builder has no direct way to create subqueries in the FROM clause. Therefore, you need to manually construct the raw SQL statement. To do this you can use the following methods:
<code class="language-php">$sub = Abc::where(...)->groupBy(...); // Eloquent Builder 实例 $count = DB::table( DB::raw("({$sub->toSql()}) as sub") ) ->mergeBindings($sub->getQuery()) // 合并所有绑定 ->count();</code>
To ensure accurate results, be sure to merge bindings in the correct order. If you have other binding clauses, you should put them after mergeBindings()
:
<code class="language-php">$count = DB::table( DB::raw("({$sub->toSql()}) as sub") ) // ->where(...) 错误的位置 ->mergeBindings($sub->getQuery()) // 合并绑定 // ->where(...) 正确的位置 ->count();</code>
This solution provides a simple and efficient way to execute subqueries containing complex conditions and bindings.
The above is the detailed content of How to Elegantly Select from a Subquery using Laravel's Query Builder?. For more information, please follow other related articles on the PHP Chinese website!