2011-02-08 98 views
24

我想排序字符串列(包含數字)。在SQL中對包含數字的字符串列進行排序?

// SELECT `name` FROM `mytable` ORDER BY `name` ASC 
+----------+ 
+-- name --+ 
+----------+ 
+-- a 1 ---+ 
+-- a 12 --+ 
+-- a 2 ---+ 
+-- a 3 ---+ 

你看到的Mysql的自然排序算法後a 1這是確定對於大多數應用)將a 12,但我有獨特的需求,所以我想結果應該是這樣排序。

+----------+ 
+-- name --+ 
+----------+ 
+-- a 1 ---+ 
+-- a 2 ---+ 
+-- a 3 ---+ 
+-- a 12 --+ 

是否有可能與只是SQL,或者我有操縱結果集在應用程序級?

+0

是字母前綴始終對所有行的固定長度? – 2011-02-08 23:04:54

+0

不,這是一個有時重複的常規字符串。 – Ish 2011-02-08 23:06:10

+2

因此,像左邊的命令(name,1),cast(SUBSTRING(name,2)as int)`不會有效。你能提供更多不同的數據來說明你的確切需求嗎? – 2011-02-08 23:08:24

回答

36

正在進行的假設它總是WORD_space_NUMBER這應該工作:

SELECT * 
FROM  table 
ORDER BY CAST(SUBSTRING(column,LOCATE(' ',column)+1) AS SIGNED) 

使用POSITION找到空格,SUBSTRING搶到它後面的數字,然後CAST使其成爲可比價值。

如果列中有不同的模式,請告訴我,我會嘗試設計一個更好的解決方法。


編輯證明的工作:

mysql> INSERT INTO t (st) VALUES ('a 1'),('a 12'),('a 6'),('a 11'); 
Query OK, 4 rows affected (0.00 sec) 
Records: 4 Duplicates: 0 Warnings: 0 

mysql> SELECT * FROM t ORDER BY st; 
+----+------+ 
| id | st | 
+----+------+ 
| 1 | a 1 | 
| 4 | a 11 | 
| 2 | a 12 | 
| 3 | a 6 | 
+----+------+ 
4 rows in set (0.00 sec) 

mysql> SELECT * FROM t ORDER BY CAST(SUBSTRING(st,LOCATE(' ',st)+1) AS SIGNED); 
+----+------+ 
| id | st | 
+----+------+ 
| 1 | a 1 | 
| 3 | a 6 | 
| 4 | a 11 | 
| 2 | a 12 | 
+----+------+ 

mysql> INSERT INTO t (st) VALUES ('b 1'),('b 12'),('b 6'),('b 11'); 
Query OK, 4 rows affected (0.00 sec) 
Records: 4 Duplicates: 0 Warnings: 0 

mysql> SELECT * FROM t ORDER BY CAST(SUBSTRING(st,LOCATE(' ',st)+1) AS SIGNED); 
+----+------+ 
| id | st | 
+----+------+ 
| 1 | a 1 | 
| 5 | b 1 | 
| 3 | a 6 | 
| 7 | b 6 | 
| 4 | a 11 | 
| 8 | b 11 | 
| 2 | a 12 | 
| 6 | b 12 | 
+----+------+ 
8 rows in set (0.00 sec) 

mysql> SELECT * FROM t ORDER BY LEFT(st,LOCATE(' ',st)), CAST(SUBSTRING(st,LOCATE(' ',st)+1) AS SIGNED); 
+----+------+ 
| id | st | 
+----+------+ 
| 1 | a 1 | 
| 3 | a 6 | 
| 4 | a 11 | 
| 2 | a 12 | 
| 5 | b 1 | 
| 7 | b 6 | 
| 8 | b 11 | 
| 6 | b 12 | 
+----+------+ 
8 rows in set (0.00 sec) 

無視我的跛腳表/列名,但給了我正確的結果。也走得更遠一點,並添加雙重排序,以數字打破字母前綴。

編輯 SUBSTRING_INDEX將使它有點更具可讀性。

ORDER BY SUBSTRING_INDEX(st, " ", 1) ASC, CAST(SUBSTRING_INDEX(st, " ", -1) AS SIGNED) 
1

看看MySQL CAST/Convert函數。

SELECT name FROM mytable ORDER BY CAST(name AS INTEGER) ASC; 

編輯: 我讀:

我想排序字符串列 (含數字)。

...但只是看看結果集。 a實際上也是內容的一部分嗎?如果是這樣,您可以使用像MID這樣的函數來僅提取數值並進行轉換。

但如果所有行只包含a沒有變化,你不妨忽略它...

0

另一種選擇是將字符串用數字左側的空格填充(即,加字和數字之間的空間),並使用所得到的字符串進行排序,comething這樣的:

ORDER BY INSERT(
    column, 
    LOCATE(' ', column), 
    0, 
    SPACES(20 - LENGTH(column) + LOCATE(' ', column)) 
) 

的字符串被假定爲模式「字後面加號空間(S)」的,並且該數字被假定爲非負數(否則它會錯誤地排序)。硬編碼20是任意選擇的,應該是字符串的數字部分的最大可能長度。

0

在這裏,我發現了以下使用查詢另一種解決方案轉換

select * from tablename where columnname like '%a%' order by Convert(smallint,Replace(columnname,'a','')) 
1

你可以試試這個:

ORDER BY CASE 
    WHEN ISNUMERIC(column) THEN cast(column as int) 
    else ascii(column[1,1]) 
end 
相關問題