Laravel Eloquent query builder suffers grouping by a column and counting the results for the pagination due to the count being an aggregate count of the grouped rows. This function will do the count so that it counts the number of rows that are returned from the group count.
use Illuminate\Database\Query\Builder as QueryBuilder;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
trait GroupCountTrait {
/**
* Group counts are difficult as you need to count the number
* of rows rather then the count of each group.
*
* @param \Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder $query
* @return int
* @throws \InvalidArgumentException
*/
public function groupCount($query)
{
if ($query instanceof EloquentBuilder)
{
$query = $query->getQuery();
}
if (! ($query instanceof QueryBuilder))
{
throw new \InvalidArgumentException('Invalid query object given.');
}
$connection = $query->getConnection();
$count = clone $query;
$count->columns = null;
$count->aggregate = ['function' => 'count', 'columns' => ['*']];
$result = $connection->select(
'select count(*) as total from (' . $count->toSql() . ') sq',
$count->getBindings()
);
return head($result)->total;
}
}```
Well group by has performance issues for sure, you can solve that by using distinct + joins
@luknei Distinct isn't the same as group by. You can group by multiple fields for example.
This is one of the things that annoys me too. It was quite surprising to see it return incorrect results.
The count() function should already be implemented this way, but it is deliberately crippled because MySQL can't optimize subqueries.
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community