假设我有下表:
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,我想要获得最新的n个记录<每个id 3个。所以我将有以下输出:
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
我之所以回答,是因为引用的问题的答案不稳定(我会在那里对此进行评论)。
这里有一个应该有效的解决方案:
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不保证表达式的求值顺序,因此如果代码要一致地工作,这一点非常重要。
您可以通过使用变量来实现这一点。首先按相反的顺序查看结果并分配一个行号,然后过滤小于或等于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