MySQL 每组前 2 条记录

标签 mysql sql

基本上我只需要获取每个用户的最后 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/

相关文章:

php - 产品过滤器 - 计算产品数量

mysql - 如何删除多个表中的数据?

mysql - 使用 sequelize.literal() 的替换

sql - 将 'IN' 运算符与 SQL 命令对象和 C# 2.0 一起使用

php - 添加条件并连接到 laravel 中的连接表

PHP简单地将表单数据插入数据库不起作用

mysql - 如何在 mysql 中使用 parent_id 选择随机?

sql - order by 后跟从属 order by

php - INSERT INTO 数据库表,从表单不起作用。数据库

mysql - 左外连接和计数未列出所有行