在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);
至此問題解決...