目前還在高度加班中,但是本次內容怕自己忘記,好不容易解決的,所以趕緊先隨便抽點時間記錄下,也沒來得及考慮效率什么的優化問題,免得以后忘記了。
測試庫結構如下:
表名為 testtab
字段名為testnum,server
測試數據如下:
獲取最高版本號的數據sql如下:
1 WITH 2 L0 as ( 3 SELECT MAX(to_number(regexp_replace(testnum,'([[:digit:]]+).([[:digit:]]+).([[:digit:]]+)','\1'))) fir FROM TESTTAB 4 ), 5 L1 as ( 6 SELECT MAX(to_number(regexp_replace(testnum,'([[:digit:]]+).([[:digit:]]+).([[:digit:]]+)','\2'))) sec FROM TESTTAB,L0 7 where testnum like fir||'.%' 8 ), 9 L2 as ( 10 SELECT MAX(to_number(regexp_replace(testnum,'([[:digit:]]+).([[:digit:]]+).([[:digit:]]+)','\3'))) thr FROM TESTTAB,L1,L0 11 where testnum like fir||'.'||sec||'.%' 12 ) 13 select t3.* from L0,L1,L2,TESTTAB t3 where t3.testnum=fir||'.'||sec||'.'||thr;
最后得出查詢結果:
sql主要用到的函數為with as,該函數主要用處是生成一個公共臨時表,后面可復用,主要思路是分段比較,L0來獲取第一段的最大值,L1在該基礎上獲取第二段的最大值,L2在之前基礎上獲取第三段的最大值,最后將其拼接獲取最大值版本號作為查詢條件去獲取數據。
因為我們版本號是固定格式 A.B.C ,因此可以這樣寫,另外使用的數據庫為oracle,mysql的暫時沒空去考慮。
另外不能直接用oracle的MAX函數去比較,經粗略測試其比較方法類似於去除小數點並右補0進行比較大小,比如
如果確定第一段的數字是確定小於10的一位數,似乎是可以直接使用MAX的,只能說我沒試出反例來,但是也沒空去多試數據,所以不確定行不行
---------------------------------------------------------------------------------------------------------------2018-12-13 修訂-------------------------------------------------------------------------------------------------------
還是和之前一樣,還在加班中,昨天也就是上面寫的,本身思路是沒問題,分段比較肯定是最穩妥的一個辦法,但是終究因為我sql水平有限,脫離了MAX函數,我不知道該如何將上面的那個sql在我需要的查詢方法里用起來,今天想來想去,終究還是用了最原始的笨辦法,為了能用上max函數,只好這樣了,因為開發時間太緊迫,沒時間給我仔細想別的辦法了,項目畢竟要求12月底上線。
這次的思路是這樣的:利用oracle的字符串處理,將版本號類型數據進行分段處理,每段進行左補0,每段長度補充到3位數一般足夠用了,然后三段拼接,去除小數點,轉為number類型,這樣就可以利用上max函數了。
處理版本號的sql如下:
CREATE OR REPLACE function dealAppMenuVersion ( v_in varchar2) return number is v_out number(10,0); begin select to_number( lpad(SUBSTR(v_in, 1, INSTR(v_in,'.',1,1)-1),3,0) || lpad(SUBSTR(v_in, INSTR(v_in,'.',1,1)+1, INSTR(v_in,'.',1,2)-INSTR(v_in,'.',1,1)-1),3,0) || lpad(SUBSTR(v_in, INSTR(v_in,'.',1,2)+1, LENGTH(v_in)-INSTR(v_in,'.',1,2)),3,0)) into v_out from dual; return v_out; end;
測試結果如下:
在版本號可以轉化為數字進行正常處理以后,接下來就方便了,先分組,然后根據版本號排序,將每個分組中的最高版本號的那行數據取出來即可。
測試代碼如下:
這里得說說 ROW_NUMBER () OVER (PARTITION BY [field1] order by [field2] asc/desc) 這個oracle提供的函數,很好用,很久以前用過但是我給忘記了,這里自己記錄下防止又忘記了,因為公司mysql用的比較多,oracle用的少函數很容易忘記。
這個函數大致意思上是根據field1進行分組,在該分組上按field2進行排序,還是我剛才的測試數據,效果圖展示如下: