获取每个组的最新 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 条记录的主要内容,如果未能解决你的问题,请参考以下文章