[英]Laravel 5 - multi-dimensional groupBy, orderBy & paginate
I have a Post model and I am trying to ->paginate()
, ->groupBy()
and ->orderBy()
. 我有一个Post模型,我正在尝试
->paginate()
, ->groupBy()
和->orderBy()
。
public function index()
{
$posts = Post::where('verified', '1')
->orderBy('created_at','desc')
->groupBy('topic', 'publisher_id')
->paginate(5);
// dd($posts);
}
Meanwhile, data in Database looks like this: 同时,数据库中的数据如下所示:
| id | verified | topic | publisher_id | body | created_at |
| 25 | 1 | Forest | 3 | EE | 10.12.50 |
| 24 | 1 | Forest | 3 | DD | 10.11.40 |
| 23 | 1 | Forest | 3 | CC | 10.10.30 |
| 22 | 1 | Dance | 2 | BB | 9.50.50 |
| 21 | 1 | Dance | 2 | AA | 9.40.40 |
| 20 | 1 | Music | 1 | ZZ | 9.30.30 |
| 19 | 1 | Music | 1 | XX | 9.20.20 |
| 18 | 1 | Art | 1 | YY | 9.10.10 |
| 17 | 1 | Art | 1 | WW | 9.00.00 |
| 16 | 1 | Ski | 2 | KK | 7.00.00 |
When I uncomment the the dd()
and run the code, I get this log: 当我取消注释
dd()
并运行代码时,我得到这个日志:
LengthAwarePaginator {
...
items : {
items : {
0 => Post{..}
1 => Post{..}
2 => Post{..}
3 => Post{..}
...
}
}
...
}
0 => Post{#249} : "published_by: "3", "body": "CC", "created_at": "10.10.30"
1 => Post{#250} : "published_by: "1", "body": "XX", "created_at": "9.20.20"
2 => Post{#251} : "published_by: "1", "body": "WW", "created_at": "9.00.00"
3 => Post{#252} : "published_by: "2", "body": "KK", "created_at": "7.00.00"
It looks so weird for a reason. 看起来很奇怪有一个原因。 It did
groupBy
for user-3, but not for others. 它为user-3做了
groupBy
,但对其他用户没有。 Also, it's pulling the earliest created at rather than latest. 而且,它是最早创造的而不是最新的。 Changing
desc
to asc
like ->orderBy('created_at', 'asc')
would put everything completely out of track. 将
desc
更改为asc
like ->orderBy('created_at', 'asc')
会使所有内容完全脱离轨道。
In other words, returning 'CC' for user-3, Forest
instead of 'EE' for user-3, Forest
换句话说,
'CC' for user-3, Forest
返回'CC' for user-3, Forest
返回'CC' for user-3, Forest
而不是'EE' for user-3, Forest
Then I thought maybe it's the ->paginate(5)
messing things up. 然后我想也许是
->paginate(5)
搞砸了。
public function post()
{
$posts = Post::where...
...
->paginate(5);
$postsTry = Post::where('verified', '1')
->orderBy('created_at','desc')
->groupBy('topic', 'publisher_id')
->get();
// dd($postsTry);
}
I get a Collection with only the items
like above object in it. 我得到一个只有上面对象的
items
的集合。 ( 0 => Post{..}, 1 => Post{..}, 2 => Post{..}
). (
0 => Post{..}, 1 => Post{..}, 2 => Post{..}
)。
It's grouping data as being earliest first rather than latest first . 它将数据分组为最早的,而不是最新的 。 What I am missing?
我错过了什么? What is the thing I am doing wrong?
我做错了什么?
To wrap up, note that what I want to get is:
总结一下, 请注意我想要的是:
'EE' for user-3, Forest
'BB' for user-2, Dance
'ZZ' for user-1, Music
'YY' for user-1, Art
Removed my previous answer but will still include the note from Laravel Pagination about chaining groupBy()
with paginate()
. 删除了我之前的答案,但仍将包含Laravel分页中关于使用
paginate()
链接groupBy()
的注释。
Note: Currently, pagination operations that use a
groupBy
statement cannot be executed efficiently by Laravel.注意:目前,
groupBy
无法有效地执行使用groupBy
语句的分页操作。 If you need to use agroupBy
with a paginated result set, it is recommended that you query the database and create a paginator manually.如果需要将
groupBy
与分页结果集一起使用,建议您查询数据库并手动创建分页器。
UPDATE UPDATE
Due to your unusual date format for the created_at
field, you'll need integer cast
ed values for it to used by the order by
statement properly (as an integer, not a string). 由于对你的不寻常的日期格式
created_at
领域,你需要整cast
于所使用的为它编值order by
适当的语句(如一个整数,而不是字符串)。 Here's a working example: 这是一个有效的例子:
Post::selectRaw("*, CAST(REPLACE(created_at, '.', '') AS UNSIGNED INTEGER) ca")
->where('verified', '1')
->orderBy('ca', 'desc')
->groupBy('topic', 'publisher_id')
->paginate();
You'll need to use a subquery (or another join method) to get the top item in your group. 您需要使用子查询(或其他连接方法)来获取组中的顶级项目。 See Getting The Rows Holding the Group-wise Maximum of a Certain Column
请参阅获取行保持某个列的组最大值
Removed my example. 删除了我的例子。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.