Lets say I have the following table:
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
for n = 3, I want to get the latest n records<=3 for each id. So I will have the following output:
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
I am answering because the referenced question has an unstable answer (I'll comment on that there).
Here is a solution that should work:
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;
The difference in the solutions is that the variable assignments are all in a single expression. MySQL does not guarantee the order of evaluation of expressions, so this is very important if the code is going to work consistently.
You could do this with the use of variables. First go through the results in reverse order and assign a row number, then filter the results for row numbers less or equal to 3, and re-order:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.