8

我一直在尝试解决这个问题一段时间,但似乎无法让它发挥作用。我有一张看起来与此类似的表。

表:问题

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

我的问题是我需要对其进行排序(简单!)但是,我只想获取每本杂志中的一本(列杂志 ID)。

到目前为止,我的 Eloquent 查询是:

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

我认为添加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

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

4

3 回答 3

14

您需要在子句中为要按结束顺序排序的每一列添加一个MAX函数。反之则适用于按结束顺序排列的列,您需要在子句中添加函数。SELECTDESCASCMINSELECT

您的 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();

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


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

->select(DB::raw('*, max(year) as year, max(yearly_issue) as yearly_issue'))

我认为将*选择器放在前面会使聚合函数覆盖它们的列。

于 2013-08-10T22:03:36.533 回答
4

我一直在寻找一种在分组之前对结果进行排序的方法,而这个答案不断出现。就我而言,它是针对用户的消息收件箱的。我需要在用户参与的每个消息线程中显示用户收到的最新消息。我的表如下所示:

--------------------------------------------------------------------
| id | sender_id | receiver_id | message | created_at | updated_at |
--------------------------------------------------------------------
|    |           |             |         |            |            |
--------------------------------------------------------------------

这个问题的公认答案对结果进行分组,然后对它们进行排序。created_at在对结果进行分组之前,我需要按字段降序对结果进行排序,以便从每个线程中获取最新消息。无论如何,这是我经过大量挖掘后的最终解决方案:

$sub = $query->orderBy('created_at', 'desc');
return $query->select('*')
             ->from(DB::raw("({$sub->toSql()}) as sub"))
             ->groupBy('sender_id');

这构造了以下查询:

select * from (
    select * from `messages`
    order by `created_at` desc
) as sub
group by `sender_id`
于 2014-09-10T19:31:59.057 回答
0

在 MySQL 中,您可以执行以下操作:

select * 
    from `UserTable` 
where userId=3
    group by `field` desc
    order by `dateActivityComplete` ;

在 eloquent 中,你会做这样的事情:->groupBy('field','desc'),然而,在 eloquent 中排序 groupBy 似乎不像 order by 那样是一个选项。

可能是您必须使用原始查询的实例,或者可能是 max 函数。

韦德

于 2015-03-23T17:16:43.783 回答