SQL分组排序后取每组最新⼀条数据的另⼀种思路mysql group by order by
在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 = 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 (⼦查询) ... 参考地址:
为了⼀个⼦查询再新建⼀个实体类...虽然觉得这样有点⿇烦但是我还是搜索了⼀下整个项⽬看有没有类似的做法,结果⼀个都没有到!
这时候我请教了⼀下部门的⽼⼈想看看他们做这类查询是如何处理的,⼤佬给出的⽅案是换⼀种sql写法
如下:
select * from table_name t1 where t1.update_time= (select max(t.update_time) from table_name t where t.id= t1.id);
⾄此问题解决...