SQL分组排序后取每组最新一条数据的另一种思路

时间:2023-12-12 14:13:56

在hibernate框架和mysql、oracle两种数据库兼容的项目中实现查询每个id最新更新的一条数据。

之前工作中一直用的mybatis+oracle数据库这种,一般写这类分组排序取每组最新一条数据的sql都是使用row_number() over()函数来实现

例如:

select t1.* from (

  select t.*,

        ROW_NUMBER() over(partition t.id order by t.update_time desc) as rn

  from table_name t

) t1 where t1.rn = 1;

但是新公司项目是兼容mysql和oracle两种数据库切换的,那么row_number() over()在使用mysql的情况下会出现错误,所以我在网上查找了一下mysql实现分组排序取最新数据的例子

有两种写法,如下:

第一种

select t1.*

from table_name t1,

   (select t.id, max(t.update_time) as uTime from table_name t group by t.id) t2

where 1=1

and t1.id = t2.id

and t1.update_time = t2.uTime;

第二种(这里limit是为了固定子查询中的排序,如果没有这个limit,外层使用虚拟表t1进行group by的时候就不会根据之前update_time排好的倒序进行分组了。limit具体的数字可以根据要查询数据的总数来决定。)

select t1.* from (

  select * from table_name t order by t.update_time desc limit 1000

) t1 group by t1.id;

这里又遇到了一个问题,虽然第一种方式使用mysql和oracle都可以查询,但是hibernate是不支持from (子查询) ... 这种结构的sql的,因为hibernate的核心是面向对象而非面向数据库,网上搜到是这种解决方案

解决hibernate不支持from (子查询) ... 参考地址:https://blog.csdn.net/fableking/article/details/3167081

为了一个子查询再新建一个实体类...虽然觉得这样有点麻烦但是我还是搜索了一下整个项目看有没有类似的做法,结果一个都没有找到!

这时候我请教了一下部门的老人想看看他们做这类查询是如何处理的,大佬给出的方案是换一种sql写法

如下:

select * from table_name t1 where t1.update_time= (select max(t.update_time) from table_name t where t.id= t1.id);

至此问题解决...