Description
- Laravel Version: 5.3.9
- PHP Version: 7.0.8
- Database Driver & Version:5.7.12
Description:
The problem appears when get some results from database using query builder. If apply first having method and after paginate will generate sql error that variable used in having clause is not in select.
paginate() method have second param as an array of columns for select, but output sql is have error because generate something like select count(*,my_having_variable).
Ex :
$distance = DB::raw('( 6371 * ACOS( COS( RADIANS('.$post['lat'].') ) * COS( RADIANS( lat ) ) * COS( RADIANS( lng ) - RADIANS('.$post['lng'].') ) + SIN( RADIANS('.$post['lat'].') ) * SIN( RADIANS( lat ) ) ) ) as distance');
$profiles = DB::table('profiles')->select('profiles.*','profiles.id as profile_id', $distance); $dist = 20; $profiles->having('distance', '<=', $dist);
$results = $profiles->paginate(8); // like that i get error that "distance" is not defined because
paginate select just count(*)`
I need use :
$results = $profiles->paginate(8,['*',$distance]);
for not have this error but i get another error because it's generating a sql like that :
select count(*,( 6371 * ACOS( COS( RADIANS ..... as distance) as aggregate
and not
select count(*) as aggregate, ( 6371 * ACOS( COS( RADIANS ..... as distance
how I think should be
The problem is not correct interpretation in function compileAggregate from Grammar.php.
I modify there like that :
`$sql = 'select ';
$column = $aggregate['columns'][0];
$addSelect = '';
if (count($aggregate['columns']) > 1) {
for ($i = 1; $i < count($aggregate['columns']); $i++) {
$addSelect .= ',' .$aggregate['columns'][$i];
}
}
$sql .= $aggregate['function'].'('.$column.') as aggregate' . $addSelect;
return $sql;`
And before call paginate need to add DB::unprepared("SET sql_mode = ''");
if you have having.
I know is not universal solution because is not even taken in consideration if use distinct but for me solves the problem.