【问题标题】:Getting the latest n records for each group获取每个组的最新 n 条记录
【发布时间】:2016-11-26 20:43:30
【问题描述】:

假设我有下表:

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

【问题讨论】:

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

标签: mysql sql 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

【讨论】:

    猜你喜欢
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-22
    • 2018-06-14
    • 1970-01-01
    相关资源
    最近更新 更多