如何使用Eloquent订购分组结果?

And*_*eas 8 laravel eloquent

我一直试图解决这个问题已经有一段时间了,似乎无法让它发挥作用.我有一张看起来与此类似的表.

表:问题

id  yearly_issue    year    stock   created_at      updated_at      magazine_id 
1   10              2000    1       [timestamp]     [timestamp]     3
2   12              1994    6       [timestamp]     [timestamp]     10
3   36              2007    10      [timestamp]     [timestamp]     102
4   6               2002    7       [timestamp]     [timestamp]     7
5   6               2002    2       [timestamp]     [timestamp]     5
6   12              2003    9       [timestamp]     [timestamp]     10
7   11              2003    12      [timestamp]     [timestamp]     10
Run Code Online (Sandbox Code Playgroud)

我的问题是我需要对它进行排序(简单!)但是,我只想获得每个杂志中的一个(专栏magazine_id).

我现在的Eloquent查询是:

$issues = Issue::where('stock', ($all ? '>=' : '>'), 0)
  ->orderBy('year', 'desc')
  ->orderBy('yearly_issue', 'desc')
  ->take($perpage)
  ->get();
Run Code Online (Sandbox Code Playgroud)

我认为添加groupBy('magazine_id')会有所帮助,但似乎它只是部分帮助我.结果的顺序不正确.所以,我的问题是 - 有什么简单的方法吗?

我一直在尝试各种类似问题的答案,但我完全没有实现它.

检索每个组中的最后一条记录

要么

如何使用GROUP BY获取每组中的最新记录?

将非常感谢更多的帮助.

编辑:我目前最接近的是:

SELECT i1.*, c.name AS image, m.title AS title
FROM issues i1
INNER JOIN covers c ON i1.id = c.issue_id
INNER JOIN magazines m ON i1.magazine_id = m.id
JOIN (SELECT magazine_id, MAX(year) year, MAX(yearly_issue) yearly_issue FROM issues GROUP BY magazine_id) i2
ON i1.magazine_id = i2.magazine_id
AND i1.year = i2.year
-- AND i1.yearly_issue = i2.yearly_issue
WHERE i1.stock ($all ? '>=' : '>') 0
ORDER BY i1.year DESC, i1.yearly_issue DESC
LIMIT $perpage
Run Code Online (Sandbox Code Playgroud)

但是,它根本没有给我想要的结果.

Rub*_*zzo 13

您需要MAXSELECT子句中为要按DESC结束顺序排序的每个列添加一个函数.对于以ASC结束顺序排序的列,反转,您需要MINSELECT子句中添加函数.

您的Eloquent查询必须包含原始选择:

$issues = DB::table('issues')
    ->select(DB::raw('id, max(year) as year, max(yearly_issue) as yearly_issue, stock, created_at, updated_at, magazine_id'))
    ->groupBy('magazine_id')
    ->orderBy('year', 'desc')
    ->orderBy('yearly_issue', 'desc')
    ->take(10)
    ->get();
Run Code Online (Sandbox Code Playgroud)

唯一的缺点是您需要指定要检索的每个列.并且不使用*选择器,它将覆盖select子句中的聚合函数.


更新:似乎在子句中的聚合函数之前添加*选择器.这意味着您将原始选择重写为:SELECT

->select(DB::raw('*, max(year) as year, max(yearly_issue) as yearly_issue'))
Run Code Online (Sandbox Code Playgroud)

我认为*之前放置选择器会使聚合函数覆盖它们的列.