Mysql 根据参数对查询结果进行分组和排序

Mysql 根据参数对查询结果进行分组和排序,mysql,sql,database,database-design,Mysql,Sql,Database,Database Design,这是我在mysql中的db表,该表中还有许多其他列。我想得到myid=1的所有行。结果应根据id分组,并按时间戳排序。查询应根据参数限制ID组 限值为3时的预期结果 id | myid | timestamp --------------------------------- 1001 | 1 | 2021-03-15 12:10:52 1001 | 1 | 2021-03-14 12:10:52 1001 | 1 | 2021-03-16 12:10:

这是我在mysql中的db表,该表中还有许多其他列。我想得到myid=1的所有行。结果应根据id分组,并按时间戳排序。查询应根据参数限制ID组

限值为3时的预期结果

id   | myid | timestamp
---------------------------------
1001  | 1     | 2021-03-15 12:10:52  
1001  | 1     | 2021-03-14 12:10:52  
1001  | 1     | 2021-03-16 12:10:52  
1002  | 2     | 2021-03-15 11:10:52  
1002  | 2     | 2021-03-16 10:10:52    
1005  | 1     | 2021-03-16 12:10:52    
1005  | 1     | 2021-03-10 12:10:52    
1004  | 4     | 2021-03-16 12:10:52  
1004  | 4     | 2021-03-16 12:17:52    
1003  | 1     | 2021-03-12 12:10:52    
1003  | 1     | 2021-03-11 12:18:52    

限制为2时的预期结果

id   | myid | timestamp
---------------------------------
1005  | 1     | 2021-03-16 12:10:52    
1005  | 1     | 2021-03-10 12:10:52  
1003  | 1     | 2021-03-12 12:10:52    
1003  | 1     | 2021-03-11 12:18:52
1001  | 1     | 2021-03-16 12:10:52 
1001  | 1     | 2021-03-15 12:10:52   
1001  | 1     | 2021-03-14 12:10:52  
在MySQL 8+上,我们可以使用COUNT作为分析函数:

以cte为例 按id cnt在分区上选择*,计数* 从你的桌子上 其中myid=1 -三人一组 选择id、myid、时间戳 来自cte 其中cnt=3 按id DESC排序,时间戳DESC; -2人一组 选择id、myid、时间戳 来自cte 其中cnt=2 按id DESC排序,时间戳DESC; 选择t1* 从测试t1开始 加入选择t2.id,t2.myid 从测试t2开始 其中t2.myid=@myid 按t2.id、t2.myid分组 拥有COUNT*我想你想要:

id   | myid | timestamp
---------------------------------
1005  | 1     | 2021-03-16 12:10:52    
1005  | 1     | 2021-03-10 12:10:52  
1003  | 1     | 2021-03-12 12:10:52    
1003  | 1     | 2021-03-11 12:18:52

这将按最小时间戳枚举每组id,然后使用最小时间戳确定要返回的组。

您提到应根据id对结果进行分组并按时间戳排序,但您显示的结果不按时间戳排序。是的,时间戳按降序排序。这看起来很棒。谢谢你,蒂姆。当我需要将查询转换为JOOQ以在我的应用程序中使用时,您可以发送一个查询来获取结果吗?仅需将CTE内联到查询中即可。您正在使用MySQL 8+?否:。我使用的是mysql 5.7,那么你就不能使用我的答案了,在mysql 5.7上实现你的输出是相当困难的。我建议升级。
select t.*
from (select t.*,
             dense_rank() over (partition by myid order by min_timeastamp, id) as seqnum
      from (select t.*,
                   min(timestamp) over (partition by myid, id) as min_timestamp
            from t
            where myid = 1
           ) t
     ) t
where seqnum <= 2;