我想要做的是将具有相同主题的用户撰写的评论分组,并获得最新的(最新的)评论。我尝试使用Comment::where()->orderBy()->groupBy()
,但它没有按预期返回数据。
这是我的数据库:
| id | receiver_id | sender_id | title | body | created_at |
| 13 | 2 | 5 | Art | DD | 12.30... |
| 12 | 2 | 5 | Art | CC | 12.20... |
| 11 | 2 | 5 | Art | BB | 12.10... |
| 10 | 2 | 5 | Art | AA | 12.00... |
| 9 | 2 | 3 | Msc | XX | 11.30... |
| 8 | 2 | 3 | Msc | YY | 11.20... |
| 7 | 2 | 3 | Msc | ZZ | 11.10... |
| 6 | 2 | 2 | Foo | UU | 10.40... |
| 5 | 2 | 2 | Foo | II | 10.30... |
| 4 | 2 | 2 | You | QQ | 10.20... |
| 3 | 2 | 2 | You | WW | 10.10... |
| 2 | 2 | 3 | Msc | LL | 10.00... |
| 1 | 2 | 4 | CSS | VV | 10.30... |
| 0 | 2 | 4 | CSS | NN | 10.20... |
我意识到,created_at和id的顺序相同。所以,我决定使用id desc
,因为我可能无法在created_at
字符串中安排日期整数。这就是我试过的:
$comment = Comment::where('receiver_id', Auth::user()->id)
->orderBy('id','desc')
->groupBy('sender_id', 'title')
->paginate(5);
dd($comment);
我想得到的结果是:
0 => Comment { id = 13, sender_id = 5, title = Art, body = DD }
(最新created_at)
1 => Comment { id = 9, sender_id = 3, title = Msc, body = XX }
2 => Comment { id = 6, sender_id = 2, title = Foo, body = UU }
3 => Comment { id = 4, sender_id = 2, title = You, body = QQ }
4 => Comment { id = 1, sender_id = 4, title = CSS, body = VV }
然而,这显示如下:
0 => Comment { id = 10, sender_id = 5, title = Art, body = AA }
1 => Comment { id = 5, sender_id = 2, title = Foo, body = II }
2 => Comment { id = 3, sender_id = 2, title = You, body = WW }
3 => Comment { id = 2, sender_id = 3, title = Msc, body = LL }
4 => Comment { id = 0, sender_id = 4, title = CSS, body = NN }
它提供了最新的评论,但却是最早的评论。
它完全跳过User User-3并显示User-2的2x主题
然后在完成User2的2x主题后,而不是在'Art'之后显示User-3。
当我在上述查询中删除->paginate()
并尝试->toSql()
时,我会收到:
"select * from `comments` where `receiver_id` = ? group by `title`, `sender_id` order by `id` desc"
我认为order by id desc
部分是在错误的位置创建的,所以这可能会导致问题。但是,我不确定。
此外,当我首先交换->orderBy()
和->groupBy
的地点(例如->groupBy()
,然后->orderBy()
)时,它会返回完全相同的结果。
最后,我尝试更换->orderBy('title', 'sender_id')
,但同样的结果也是如此。
我做错了什么或错过了什么?提前谢谢。
答案 0 :(得分:1)
你的问题是关于mysql group by在订购之前被解雇了。
解决方案应该有一个内连接:
Comment::join(\DB::raw('(select max(id) as id from comments group by sender_id) t'),function($join){
$join->on('comments.id', '=', 't.id');
})->where('comments.receiver_id', Auth::user()->id)
->orderBy('id','desc')
->paginate(5);
类似于: