2010-01-12 82 views
3

我相信這肯定是一個很常見的問題,所以我猜測微軟已經解決了這個問題。我的谷歌搜索技能只是沒有達到劃痕。我有要訂購由一個字段,它是一個varchar字段,例如如何在可以按字母順序包含數字的varchar字段上進行排序?

  • Q
  • 貨號10
  • 貨號1
  • 貨號9
  • 貨號2
  • F

現在我期待結果是

  • ˚F
  • 貨號1
  • 貨號2
  • 貨號9
  • 貨號10
  • Q

但是事實並非如此。它是如下(請注意,貨號10來貨號1且不貨號9如預期之後)

  • ˚F
  • 貨號1
  • 貨號10
  • 貨號2
  • 貨號9
  • Q

現在我知道原因了爲此,你不需要解釋:)但我不記得如何解決它,或者如果有一個漂亮的標誌或命令,我可以用它來正確的。

編輯:

上面的例子只是一個例子。該列可以包含任何值。字母和數字的任意組合。有沒有辦法按字母順序排序,而不是按字母順序排序的ASCII值?

編輯2: 感謝迄今爲止的答案。我正在談論任何一個任意的數據。如果它是在一個固定的位置或者在某個東西之前,那麼它很容易,我不會問。我要求用任何任意的數據來解決這個問題。不是模式,沒有規則,沒有任何東西。

+1

數字值總是以文本「Num」開頭嗎? – 2010-01-12 20:34:18

+0

重新編輯2:在某些情況下可以使用一般解決方案,但我沒有對*自然排序*的嚴格定義。你如何期待它的表現?提供更復雜的用例將有很大幫助。我已經寫了一個CLR函數,它似乎適用於**我**的需求,請參閱下面的編輯。 – RedFilter 2010-01-14 12:35:38

+0

@OrbMan。我真的希望像SELECT * FROM x ORDER BY(NaturalIndex(col))或類似的東西。我想可能這個問題已經被SQL Server解決了,我只是沒有意識到這個功能。我將通過C#中的解決方案實現,使用Yada發佈的鏈接。不管怎麼說,還是要謝謝你。 – uriDium 2010-01-14 13:21:14

回答

2

這爲ASCII排序的與自然排序的老問題

進一步詳情,請參閱http://www.codinghorror.com/blog/archives/001018.html

+0

我將翻譯以下C++ http://www.stereopsis.com/strcmp4humans。HTML到C#中,並將在C#中處理結果集。我希望有一個簡單的方法可以在SQL Server中完成,但我認爲沒有。 – uriDium 2010-01-14 13:19:16

1

如果該字段總是在末尾有可能有一個單詞的數字,並且之前有一個空格,那麼可以使用CHARINDEX/SUBSTRING來解決此問題。

下面是一個例子:

select * 
from (
    select 'Q' x 
    union 
    select 'Num 10' 
    union 
    select 'Num 1' 
    union 
    select 'A' 
    union 
    select 'Num 9' 
    union 
    select 'Num 2' 
    union 
    select 'F' 
) a 
order by 
    case 
     when CHARINDEX(' ', x) <> 0 then LEFT(x, CHARINDEX(' ', x) - 1) 
     else x 
    end, 
    cast(case 
     when CHARINDEX(' ', x) <> 0 then substring(x, CHARINDEX(' ', x) + 1, LEN(x) - CHARINDEX(' ', x)) 
     else '' 
    end as int) 

從這個輸出是:

A 
F 
Num 1 
Num 2 
Num 9 
Num 10 
Q 

編輯:

因爲你的數據是不夠的一致使用硬編碼方法,該解決方案要求採取更激烈的措施。我已經嘗試過基於T-SQL的函數,它會給出一種自然排序的形式,但是發現它們太慢而無法使用。相反,我寫了一個基於CLR的函數,它的表現非常好。該函數返回一個可以排序的標量值。您將在over here找到代碼和安裝說明。

+0

@UriDium:查看我的編輯。 – RedFilter 2010-01-14 12:29:54

1

您加入

列可以包含任意值。字母和數字的任意組合

那麼,你想在哪裏「foo1bar」和「foo10bar」爲例?或者「foo10bar11」和「foo10bar1」?或者「Foo Two」和「Foo Three」?

沒有明智的解決方案沒有明智的數據。你有隨機數據。定義「人類可讀」。

1

「我問了一個通用的解決方案,以 這個問題與任何arbitary數據。 沒有模式,沒有規矩,什麼都沒有。」

問題是,編程是關於尋找模式,從模式中派生規則並基於這些規則應用解決方案。所以如果沒有這些先決條件,你的問題就非常棘手。

基本上你所要做的就是將你的排序字符串標記爲純字母塊和純數字塊,並對每個類別應用不同的排序順序。這是可行的,只要你有某種模式,例如

AAA999AA 
    A9AAAAA 
    A999A 

但它需要對每個圖案的定製解決方案。任何任意數據安排的通用解決方案都是一個很大的問題。

相關問題