最近在做項目中,有一個需求需要查詢根據合同的狀态去修改對應的業務單對應的狀态,合同和業務單存在同一張表中,而且同一個業務A可能存在多條業務單的情況,需要一條SQL查詢出每條業務對應的日期最新的那條業務單來操作。按自己平時的SQL習慣首先想到子查詢實作:如下
--其中serviceconstid代表一條業務A,每條業務對應的值不同
select M.*
from CM_CONTRACT_INSTANCE M
where M.createtime =
(select max(t.createtime)
from cm_contract_instance t
where t.serviceconstid = M.serviceconstid);
但是如上發現一個問題,如果存在業務A下存在兩條一模一樣createtime的業務單,那這條SQL查出來的資料就會把對應的兩條業務單都查出來,但是現在隻想取其中一條來操作,這裡就不滿足需求了!
第二種查詢方式如下
-- 結果準确,但是效率較差
SELECT B.*
FROM (SELECT A.*,
ROW_NUMBER() OVER(partition by A.serviceconstid order by A.createTime desc nulls last) rn
FROM CM_CONTRACT_INSTANCE A) B
WHERE RN = 1;
第三種方式,使用分組函數group by
select A.*
from CM_CONTRACT_INSTANCE A,
(select serviceconstid, max(createTime) createTime from CM_CONTRACT_INSTANCE group by serviceconstid) B
where A.serviceconstid = B.serviceconstid
and A.createTime = B.createTime
order by A.serviceconstid;
第四中方式(和第三種類似)
select A.*
from CM_CONTRACT_INSTANCE A
inner join (select serviceconstid, max(createTime) createTime from CM_CONTRACT_INSTANCE group by serviceconstid) B
on A.serviceconstid = B.serviceconstid
and A.createTime = B.createTime
order by A.serviceconstid;
後面兩種方式也會出現第一種那個問題,不過由于系統中資料量不大,執行效率差别不大,後續可以在觀察一下!
如果建立時間非正常則,是不會出現相同的情況,是以上面四中方法都可以滿足需求。