获取每个组的最新 n 条记录

Posted

技术标签:

【中文标题】获取每个组的最新 n 条记录【英文标题】:Getting the latest n records for each group 【发布时间】:2016-07-22 20:49:28 【问题描述】:

假设我有下表:

id  coulmn_id  value    date
1      10      'a'     2016-04-01
1      11      'b'     2015-10-02
1      12      'a'     2016-07-03
1      13      'a'     2015-11-11
2      11      'c'     2016-01-10
2      23      'd'     2016-01-11
3      11      'c'     2016-01-09
3      111     'd'     2016-01-11
3      222      'c'     2016-01-10
3      333      'd'     2016-01-11

对于 n = 3,我想为每个 id 获取最新的 n 条记录

id  column_id  value    date
1      10        'a'     2016-04-01
1      12        'a'     2016-07-03
1      13        'a'     2015-11-11
2      11        'c'     2016-01-10
2      23        'd'     2016-01-11
3      111       'd'     2016-01-11
3      222       'c'     2016-01-10
3      333       'd'     2016-01-11

【问题讨论】:

***.com/questions/12113699/… 你的主键是什么? 上述问题的解决方案适用于有限数量的'group_name',日期字段可以很大.. 主键 = id 和 column_id。我已经相应地更新了表格。 查看带有greatest-n-per-group标签的问题。这个问题已经回答了很多次了。 【参考方案1】:

我正在回答,因为引用的问题的答案不稳定(我会在那里对此发表评论)。

这是一个应该可行的解决方案:

select t.*
from (select t.*,
             (@rn := if(@id = id, @rn + 1,
                        if(@id := id, 1, 1)
                       )
             ) as seqnum
      from t cross join
           (select @rn := 0, @id := -1) params
      order by id, date desc
     ) t
where seqnum <= 3;

解决方案的不同之处在于变量赋值都在一个表达式中。 mysql 不保证表达式的求值顺序,因此如果代码要始终如一地工作,这一点非常重要。

【讨论】:

我并不是要在这种类型的多个答案中打扰您,这更多是问题发布者需要整理的,但从技术上讲,如果 date 字段为不是唯一的。 只是添加一个好的答案。 @Uueerdo 。 . .这是一个合理的观察。但是,除非 data 有问题,否则答案是正确的。从数据库的角度来看,引用的答案可能不正确。【参考方案2】:

您可以通过使用变量来做到这一点。先逆序遍历结果并分配一个行号,然后对小于或等于3的行号过滤结果,重新排序:

select   id, value, date
from     (
           select      id, value, date,
                       @rn := if(@id = id, @rn+1, if (@id := id, 1, 1)) rn
           from        mytable,
           cross join  (@id := null, @rn := null) init
           order by    id, date desc
         ) as base
where    rn <= 3
order by id, date asc

【讨论】:

以上是关于获取每个组的最新 n 条记录的主要内容,如果未能解决你的问题,请参考以下文章

MSSQL分组取后每一组的最新一条记录

每个项目 mongodb 组的最新记录(按日期)

从mongoDB集合中获取N条最新记录时的回调函数[重复]

SQLSERVER 查询分组后获取每组的最新一条数据

有重复组时选择最后一组的第一条记录

mysql根据某个字段分组根据更新时间获取最新的记录