Laravel groupBy 带分页

问题描述 投票:0回答:6

我正在尝试使用 queryBuilder 获取一张表中的所有结果,按 15 个字段分组分页。

$data['invoices'] = InvoiceModel::selectRaw("*")
    ->groupBy('serie')
    ->paginate(15);

Laravel 抛出以下错误:

SQLSTATE[42000]:语法错误或访问冲突:1055 SELECT 列表的表达式 #1 不在 GROUP BY 子句中,并且包含非聚合列“projetoservidor.vendas_195295269.id”,该列在功能上不依赖于 GROUP BY 子句中的列;这与 sql_mode=only_full_group_by (SQL: select count(*) asaggregate from (select * from

vendas_195295269
group by
serie
) as
aggregate_table
)

不兼容

我该怎么办?

laravel
6个回答
7
投票

Laravel 不支持带有分页的 groupBy

在 Laravel 文档中阅读更多内容:

更新

上述警告已从 Laravel 8.x 文档中删除。 @ronline 在评论中确认,从那时起,使用 groupBy 的分页操作已经被整理出来。


4
投票

不幸的是,Laravel 不支持 Eloquent 的 groupBy 分页,因为它的情况很复杂。 但这里有一个提示,如果您在获取数据后使用集合的

groupBy
并且您希望保持分页对象看起来相同。

// Get the activities
$activities = $user->activities()->paginate(6);

// This will replace data property of the pagination
$activities->setCollection($activities->groupBy('type'));

现在

$activities
看起来会和分组之前一样

{
   "current_page": 1,
   "data": {
       "type_1": [
           ...
       ],
       "type_2": [
           ...
       ]
   },
   "first_page_url": "http://URL? 
   page=1",
   "from": 1,
   "last_page": 
   ...
}

3
投票

将此功能与任何 Laravel 版本一起使用。它对我有用

$draws = Draw::with('location')->select('location_id', 'draw_number', 'created_at')
        ->paginate(30);

$draws->setCollection($draws->groupBy(function ($date) {
    return Carbon::parse($date->created_at)->format('Y-m-d');
}));

0
投票

取自 Laravel 文档此处

目前,Laravel 无法高效执行使用 groupBy 语句的分页操作。如果您需要使用带有分页结果集的groupBy,建议您查询数据库并手动创建分页器。


0
投票

我正在使用 Laravel 查询生成器:交叉连接、分组依据、分页,它可以工作。这是工作代码。

Thread::join('participants as p', 'p.id', 'threads.id' )
   ->join('messages as m', 'm.thread_id', 'threads.id' )
   ->join('users as u', 'm.user_id', 'u.id' )
   ->select
   (
       array(
           'u.email as creator',
           'p.*',
           'threads.*',
           'threads.id as id'
          )
   )
   ->latest('threads.updated_at')
   ->groupBy('threads.id')
   ->paginate($numberOfPages)

0
投票

雄辩的关系

假设

Invoice n..1 Serie

如果

serie
Eloquent 关系,您可以使用关系模型作为分页目标进行分页分组。

Serie::with([
    'invoices',
])
    ->paginate();

您还可以按

serie
invoice

进行过滤

例如如果按发票过滤

Serie::whereIn('id', Invoice::where($condition)->select(['serie_id']))
    ->with([
        'invoices' => function ($query) use ($condition) {
            $query->where($condition);
        },
    ])
    ->paginate();

田野

如果

serie
是一个字段,分页会稍微复杂一些,但是如果select子句只包含聚合列,你仍然可以这样做。最好添加一个
order by
子句。

use Illuminate\Support\Facades\DB;

// -----

Invoice::select([
    'serie',
    DB::raw('min(column1)'),
    DB::raw('max(column2)'),
    DB::raw('avg(column3)'),
    // ...
])
    ->groupBy('serie')
    ->orderBy(DB::raw('min(column1)'), 'asc') // or desc
    ->paginate();
© www.soinside.com 2019 - 2024. All rights reserved.