在laravel 5.2中带有分页()的不同()不起作用
Posted
技术标签:
【中文标题】在laravel 5.2中带有分页()的不同()不起作用【英文标题】:distinct() with pagination() in laravel 5.2 not working 【发布时间】:2017-05-08 01:48:51 【问题描述】:我正在尝试在 laravel 5.2 中使用 distinct()
和 pagination()
流畅,它给出的结果正确但分页保持不变(就像没有应用不同)。
我已经使用我的代码查看并测试了以下答案 - laravel 5 - paginate total() of a query with distinct - Paginate & Distinct - Query Builder paginate method count number wrong when using distinct
我的代码是这样的:
DB::table('myTable1 AS T1')
->select('T1.*')
->join('myTable2 AS T2','T2.T1_id','=','T1.id')
->distinct()
->paginate(5);
示例
- 我有三个记录的结果(即 POST1、POST2、POST3 和 POST1),所以我申请了distinct()
。
- 现在我的结果是 POST1, POST2 和 POST3 但分页仍然显示为 4 条记录(作为应用之前的结果 distinct()
)。
任何建议将不胜感激!
【问题讨论】:
你能具体告诉我们什么不起作用吗?您希望看到什么,而您又看到了什么? 感谢您的回复!请参阅在我的问题中添加的 EXAMPLE.. 我仍然无法重新创建您的场景。你能上传一个数据库架构和一些行吗? 也许连接给了你重复的行,但是选择中有一些额外的字段,所以它不排除它的不同之处?尝试删除连接,或调用 ->select() 来指定您将使用哪些列。 @DiogoSgrillo 是的,加入返回重复的行集,这就是我使用distinct()
的原因,但不幸的是它不会影响分页结果。为什么?
【参考方案1】:
distinct 正在工作....当您进行连接时,它会检查所有选定列中的不同条目,这里..您在连接后获得的列名也包含在连接中...
要运行它,请将select()
添加到您的构建器实例中,它应该可以工作:)
DB::table('myTable1 AS T1')
->join('myTable2 AS T2','T2.T1_id','=','T1.id')
->select('T1.*')
->distinct()
->paginate(5);
如果这对你不起作用,请告诉我:)
【讨论】:
感谢您的回答......!我已经这样做了select()
,没有解决。实际问题就像应用distinct()
结果集返回正确的不同数据集,但分页反应与使用distinct
之前相同。我尝试了在我的问题中提到的一些链接,但没有解决我的问题。【参考方案2】:
Laravel 似乎存在一些持续存在的问题,并且在分页中使用 distinct。
在这种情况下,当分页确定记录总数时,它会忽略您在select()
子句中指定的字段。由于它忽略了您的列,因此也忽略了不同的功能。所以,count查询变成select count(*) as aggregate from ...
要解决此问题,您需要告诉 paginate 函数您的列。传递要选择的列数组作为第二个参数,它将把它们考虑到总计数中。所以,如果你这样做:
/*DB::stuff*/->paginate(5, ['T1.*']);
这将运行计数查询:
select count(distinct T1.*) as aggregate from
因此,您的查询应如下所示:
DB::table('myTable1 AS T1')
->select('T1.*')
->join('myTable2 AS T2','T2.T1_id','=','T1.id')
->distinct()
->paginate(5, ['T1.*']);
【讨论】:
是的,这是可行的解决方案,并从 origin..Thanks man..+1 中找到了它! 进一步,我将我的 codejack(放入我的答案)以绕过传递的第二个参数。你能推荐一下吗?【参考方案3】:我在我的代码中发现了问题,即我需要将$column
作为第二个参数传递给paginate($perPage, $columns, $pageName, $page)
。我从laravel git issue得到了解决方案。
所以我的工作代码:
DB::table('myTable1 AS T1')
->select('T1.*')
->join('myTable2 AS T2','T2.T1_id','=','T1.id')
->distinct()
->paginate(5, ['T1.*']);
需要建议
如果,我破解Builder.php 的代码以绕过传递第二个参数$column
。我的意思是这是好事还是任何击球手选项?
/**
* Paginate the given query into a simple paginator.
*
* @param int $perPage
* @param array $columns
* @param string $pageName
* @param int|null $page
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
public function paginate($perPage = 15, $columns = null, $pageName = 'page', $page = null)
//To solved paginator issue with distinct...
if(is_null($columns) && strpos($this->toSql(), 'distinct') !== FALSE)
$columns = $this->columns;
$columns = array_filter($columns, function($value)
return (is_string($value) && !empty($value));
);
else
//If null $column, set with default one
if(is_null($columns))
$columns = ['*'];
$page = $page ?: Paginator::resolveCurrentPage($pageName);
$total = $this->getCountForPagination($columns);
$results = $total ? $this->forPage($page, $perPage)->get($columns) : [];
return new LengthAwarePaginator($results, $total, $perPage, $page, [
'path' => Paginator::resolveCurrentPath(),
'pageName' => $pageName,
]);
【讨论】:
您无法安全地修改vendor
目录中的代码。下次您执行composer update
时,您的更改将被覆盖。这也为自动化部署、使用 CI 甚至只是手动将代码从一个地方移动到另一个地方的能力增加了极大的复杂性(您必须记住您所做的自定义更改)。
@patricus:是的,我明白了。有没有办法像补丁或更改函数(在 Drupal/WP 中)这样可以防止丢弃我的更改?【参考方案4】:
如果可能,您可以将distinct()
更改为groupBy()
。
【讨论】:
【参考方案5】:使用 groupBy() 而不是 distinct()。我没有测试,但它会工作。我在查询中遇到了同样的问题。
$author = Author::select('author_name')->groupBy('author_name')->paginate(15);
【讨论】:
【参考方案6】:使用 groupby 和分页来消除重复
【讨论】:
嗨阿兹瓦尔!我认为您的答案的内容已经被其他答案所涵盖。如果您想详细说明这些答案,我建议您在其中一个评论中这样做。【参考方案7】:在 distinct() 中传递 colom 名称
我连接了多个表,需要不同的数据。因此列表与 distinct 完美配合,但分页期间的总记录数是错误的,我进入了这个线程。后来,我能够通过在 distinct 方法中传递一个参数来解决这个问题。
DB::table('myTable1 AS T1')
->select('T1.*')
->join('myTable2 AS T2','T2.T1_id','=','T1.id')
->distinct(['T1.id'])
->paginate(5);
【讨论】:
以上是关于在laravel 5.2中带有分页()的不同()不起作用的主要内容,如果未能解决你的问题,请参考以下文章
iOS 中带有分页的 UICollectionView 的页数
Laravel 5.2 中带有 javascript 的模态视图中的动态图像