2016-09-12 113 views
5

任何人都可以幫助我如何排序?
我有一個模式的動態列表,我想排序,它包含字母數字值和字母。Sql Server 2008中的字母數字排序

CREATE TABLE dbo.Pattern (Pattern varchar(50) NULL) 
INSERT INTO dbo.Pattern (Pattern) VALUES ('A11') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('A12') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('A8') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('A2') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B6') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B21') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B10') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B3') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B100') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B2') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('AA') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('BA') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('A20') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('AB') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('BB') 

SELECT Pattern FROM dbo.Pattern ORDER BY Pattern 

DROP Table dbo.Pattern 

結果表明這樣的:

A11 
A12 
A2 
A20 
A8 
AA 
AB 
B10 
B100 
B2 
B21 
B3 
B6 
BA 
BB 

但我要表明的是這樣的結果:

AA 
A1 
A2 
A8 
A11 
A12 
A20 
AB 
BA 
B2 
B3 
B6 
B10 
B21 
B100 
BB 
+2

加1樣本數據 – TheGameiswar

+0

您可以定義所需結果背後的邏輯嗎?爲什麼'AA'會出現在'B100'之後? 「AAA」和「BA1」之間會先出現哪一個?爲什麼?如果你可以定義邏輯,我敢打賭,你很容易回答你自己的問題。 –

+0

@TabAlleman,我已經編輯了應該爲模式排序輸出的結果的內容。 – itsMacyAnn

回答

1
SELECT Pattern 
FROM dbo.Pattern 
ORDER BY LEFT(Pattern,1), 
     CASE WHEN SUBSTRING(Pattern,2,LEN(Pattern)) LIKE '%[0-9]%' THEN CAST(SUBSTRING(Pattern,2,LEN(Pattern)) as int) 
      WHEN SUBSTRING(Pattern,2,LEN(Pattern)) = 'A' THEN 0 
      ELSE 10000000 END, 
      SUBSTRING(Pattern,2,LEN(Pattern)) 

將輸出:

Pattern 
AA 
A2 
A8 
A11 
A12 
A20 
AB 
BA 
B2 
B3 
B6 
B10 
B21 
B100 
BB 
1

爲了您的樣本數據,此接近:

order by left(pattern, patindex('%[0-9]%', pattern)), 
     patindex('%[0-9]%', pattern), 
     len(pattern) asc, 
     pattern 

但是,你想全部阿爾法是最後一次,所以case需要(我認爲):

order by left(pattern, patindex('%[0-9]%', pattern)), 
     (case when pattern like '%[0-9]%' 
       then patindex('%[0-9]%', pattern) 
       else 999 
      end), 
     len(pattern) asc, 
     pattern 
+0

它沒有像上面提到的那樣返回輸出。爲什麼? – Susang

+0

那麼這個邏輯意味着'B1'會在'A10'之前出現,因爲它的長度更短。 –

+0

@Suraz。 。 。你已經有了答案,但我仍然修正了這個問題。 –

1
SELECT Pattern 
FROM dbo.Pattern 
ORDER BY CASE WHEN PATINDEX('%[0-9]%', Pattern) > 0 
       THEN LEFT(Pattern, PATINDEX('%[0-9]%', Pattern)-1) 
       ELSE Pattern 
     END, 
     CASE WHEN PATINDEX('%[0-9]%', Pattern) > 0 
       THEN CONVERT(INT, SUBSTRING(Pattern, PATINDEX('%[0-9]%', Pattern), LEN(Pattern))) 
       ELSE 0 
     END 

請在發佈前搜索網和堆棧溢出。

參考:http://www.essentialsql.com/use-sql-server-to-sort-alphanumeric-values/

+0

它返回'傳遞給LEFT或SUBSTRING函數的無效長度參數.'錯誤。拋出'AA','BA'的錯誤,因爲它們沒有數字值,所以'LEFT('AA',0 - 1)'拋出錯誤。 – Arulkumar

+0

消息537,級別16,狀態2,行1 傳遞給LEFT或SUBSTRING函數的長度參數無效。 – itsMacyAnn

+0

@ayakamacy我更新了我的答案,使用'CASE'表達式來處理只包含字母的圖案。 –

0

我會分體字母和num部分:

ORDER BY 
    CASE WHEN PATINDEX('%[0-9]%', Pattern)=0 THEN 1 ELSE 0 END,--Put no-nums last 
    CASE WHEN PATINDEX('%[0-9]%', Pattern) != 0 THEN LEFT(Pattern, PATINDEX('%[0-9]%', Pattern)-1) ELSE Pattern END, 
    CASE WHEN PATINDEX('%[0-9]%', Pattern) != 0 THEN SUBSTRING(Pattern, PATINDEX('%[0-9]%', Pattern), LEN(Pattern)) END 
0

使用交叉適用於簡化行計算

select pattern 
from pattern 
cross apply (
    select leftLen = isnull(nullif(patindex('%[0-9]%', pattern),0) - 1, len(pattern)) 
      ,totalLen = len(pattern) 
    ) c 
order by 
case leftLen when totalLen then 2 else 1 end, 
left(Pattern, leftLen), 
cast(right(Pattern, totalLen-leftLen) as int)