2010-06-16 49 views
3

我有一個表像這樣定義:如何獲得在T-SQL一個版本號(VARCHAR)列的MAX值

Column: Version  Message 
Type: varchar(20) varchar(100) 
---------------------------------- 
Row 1: 2.2.6  Message 1 
Row 2: 2.2.7  Message 2 
Row 3: 2.2.12  Message 3 
Row 4: 2.3.9  Message 4 
Row 5: 2.3.15  Message 5 

我想編寫一個T-SQL查詢,將得到消息MAX版本號,其中「版本」列表示軟件版本號。也就是說,2.2.12大於2.2.7,2.3.15大於2.3.9等。不幸的是,我不能想到一個簡單的方法來做到這一點,而不使用CHARINDEX或一些複雜的其他分裂式邏輯。運行此查詢:

SELECT MAX(Version) FROM my_table 

將產生錯誤的結果:

2.3.9

當確實應該2.3.15。任何明智的想法都不會太複雜?

回答

10

一個解決方案是使用一個表值分割功能分割的版本爲行,然後將它們合併回欄,讓你可以這樣做:

Select TOP 1 Major, Minor, Build 
From (...derived crosstab query) 
Order By Major Desc, Minor Desc, Build Desc 

其實,另一種方式是使用PARSENAME函數來分割對象名稱:

Select TOP 1 Version 
From Table 
Order By Cast(Parsename(Z.Version , 3) As Int) Desc 
    , Cast(Parsename(Z.Version , 2) As Int) Desc 
    , Cast(Parsename(Z.Version , 1) As Int) Desc 
+1

+1:OP需要對所需功能進行數據模型更改。 – 2010-06-16 22:24:46

+1

Parsename的想法很漂亮,但我不得不同意OMG--表設計將不允許所需的簡單查詢。 – 2010-06-16 22:32:20

+0

是的,我意識到如果我的數據模型不同,它會變得非常容易。維護遺留代碼有時候會很痛苦!但是,如果我有機會對此應用程序進行一些數據庫重構,我肯定會記住「最佳解決方案」。同時......我同意......很好的使用Parsename! – 2010-06-17 12:19:57

3

它是否必須在大表上有效?我建議您創建一個索引持久計算列,將版本轉換爲正確排列的格式,並在查詢中使用計算列。否則,您將始終掃描頭尾。

如果表格很小,那沒關係。然後,你可以使用一個即時的排名,使用拆分函數,或(ab)使用parsename,如托馬斯建議。

+0

有趣的想法,但不幸的是,我的真實數據是相當大的。 – 2010-06-17 19:39:48