基本上我只需要获取每个用户的最后 2 条记录,考虑到最后的 created_datetime:
id | user_id | created_datetime
1 | 34 | '2015-09-10'
2 | 34 | '2015-10-11'
3 | 34 | '2015-05-23'
4 | 34 | '2015-09-13'
5 | 159 | '2015-10-01'
6 | 159 | '2015-10-02'
7 | 159 | '2015-10-03'
8 | 159 | '2015-10-06'
返回(预期输出):
2 | 34 | '2015-10-11'
1 | 34 | '2015-09-10'
7 | 159 | '2015-10-03'
8 | 159 | '2015-10-06'
我正在尝试这个想法:
select user_id, created_datetime,
$num := if($user_id = user_id, $num + 1, 1) as row_number,
$id := user_id as dummy
from logs group by user_id
having row_number <= 2
想法是只保留前 2 行并删除所有其他行。
有什么想法吗?
最佳答案
您的想法很接近。我认为这会更好:
select u.*
from (select user_id, created_datetime,
$num := if(@user_id = user_id, @num + 1,
if(@user_id := id, 1, 1)
) as row_number
from logs cross join
(select @user_id := 0, @num := 0) params
order by user_id
) u
where row_number <= 2 ;
更改如下:
- 变量只在一个表达式中设置。 MySQL 不保证表达式求值的顺序,因此这一点很重要。
- 工作在子查询中完成,然后在外部查询中处理。
- 子查询使用
order by
, 不是group by
. - 外部查询使用
where
而不是having
(实际上,在 MySQL 中having
可以,但where
更合适)。
关于MySQL 每组前 2 条记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33093017/