Correct way described in this answer: https://mcmap.net/q/136767/-how-to-select-from-subquery-using-laravel-query-builder
Most popular answer at current moment is not totally correct.
This way https://mcmap.net/q/136767/-how-to-select-from-subquery-using-laravel-query-builder is not correct in some cases like: sub select has where bindings, then joining table to sub select, then other wheres added to all query. For example query:
select * from (select * from t1 where col1 = ?) join t2 on col1 = col2 and col3 = ? where t2.col4 = ?
To make this query you will write code like:
$subQuery = DB::query()->from('t1')->where('t1.col1', 'val1');
$query = DB::query()->from(DB::raw('('. $subQuery->toSql() . ') AS subquery'))
->mergeBindings($subQuery->getBindings());
$query->join('t2', function(JoinClause $join) {
$join->on('subquery.col1', 't2.col2');
$join->where('t2.col3', 'val3');
})->where('t2.col4', 'val4');
During executing this query, his method $query->getBindings()
will return bindings in incorrect order like ['val3', 'val1', 'val4']
in this case instead correct ['val1', 'val3', 'val4']
for raw sql described above.
One more time correct way to do this:
$subQuery = DB::query()->from('t1')->where('t1.col1', 'val1');
$query = DB::query()->fromSub($subQuery, 'subquery');
$query->join('t2', function(JoinClause $join) {
$join->on('subquery.col1', 't2.col2');
$join->where('t2.col3', 'val3');
})->where('t2.col4', 'val4');
Also bindings will be automatically and correctly merged to new query.
SELECT ... AS
in eloquent; by providing the column name as the key in an array provided to->addSelect
. E.g.$queryBuilder->addSelect([ 'name_of_generated_column' => DB::table('table_name') ->selectRaw(1) ->whereNotNull('example_column_in_example_subquery') ->limit(1) ]
; You can then use the generated column name in$queryBuilder->get(['name_of_generated_column']);
– Breaker