2017-01-07 65 views
0

排序的字母數字字符串我有一個MySQL tablewith包含值的VARCHAR列如下:SQL由數字部分

abc-1 
abc-2 
abc-10 
...etc. 

有沒有辦法把它在MySQL的順序數字部分進行排序:

abc-1 
abc-2 

代替

abc-1 
abc-10 
abc-2 

澄清數據的值

典型值是的mir-1,的mir-14,的mir-193,具有最高感的mir-4987。爲了簡化,我們假設所有都以'mir-'開頭(我可以手工處理少數例外)。

+3

請顯示數據的示例示出了可能的值的完整範圍。例如,每個值是否都以'abc'開頭? –

+1

根據數據的實際格式,您可能希望在插入時通過分析當前內容並將數值提取到單獨的列中或以其他方式派生並存儲排序鍵來解決此問題。這樣可以防止執行不能從索引獲益的查詢。 – CodeCaster

+0

@TimBiegeleisen - 完成了。 – David

回答

2

假設您的列可以包含太像這些只有如defg-12 abc-1或其他價值和您要訂購abc那些第一和他人的人後。

SELECT 
    * 
FROM 
    your_table 
ORDER BY SUBSTRING_INDEX(t, '-', 1) , CAST(SUBSTRING_INDEX(t, '-', - 1) AS UNSIGNED); 
+0

我遵循MySQL的建議,'t'應該被字段名稱替換後,它工作得很好;-)。非常感謝。 – David

1

您還可以添加1或2個虛擬列,它們會自動計算您的字符串和整數,並將其直接指定給int。那麼你也可以在這個列上使用索引。

添加虛擬列使用查詢這樣的:

ALTER TABLE your_table 
ADD s1 VARCHAR(32) GENERATED ALWAYS AS (SUBSTRING_INDEX(t, '-', 1)) STORED, 
ADD i1 INT(11)  GENERATED ALWAYS AS (SUBSTRING_INDEX(t, '-', -1)) STORED; 

樣品

mysql> SELECT * FROM your_table; 
+----+--------+ 
| id | t  | 
+----+--------+ 
| 1 | abc-2 | 
| 2 | abc-21 | 
| 3 | abc-32 | 
+----+--------+ 
3 rows in set (0,00 sec) 

mysql> ALTER TABLE your_table 
    -> ADD s1 VARCHAR(32) GENERATED ALWAYS AS (SUBSTRING_INDEX(t, '-', 1)) STORED, 
    -> ADD i1 INT(11)  GENERATED ALWAYS AS (SUBSTRING_INDEX(t, '-', -1)) STORED; 
Query OK, 3 rows affected (0,02 sec) 
Records: 3 Duplicates: 0 Warnings: 0 

mysql> SELECT * FROM your_table; 
+----+--------+------+------+ 
| id | t  | s1 | i1 | 
+----+--------+------+------+ 
| 1 | abc-2 | abc | 2 | 
| 2 | abc-21 | abc | 21 | 
| 3 | abc-32 | abc | 32 | 
+----+--------+------+------+ 
3 rows in set (0,00 sec) 

mysql> insert into your_table (id,t) VALUES(4,'abc-9876'); 
Query OK, 1 row affected (0,00 sec) 

mysql> SELECT * FROM your_table; 
+----+----------+------+------+ 
| id | t  | s1 | i1 | 
+----+----------+------+------+ 
| 1 | abc-2 | abc | 2 | 
| 2 | abc-21 | abc | 21 | 
| 3 | abc-32 | abc | 32 | 
| 4 | abc-9876 | abc | 9876 | 
+----+----------+------+------+ 
4 rows in set (0,00 sec) 

mysql> UPDATE your_table set t='abc-2211' where id = 1; 
Query OK, 1 row affected (0,01 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> SELECT * FROM your_table; 
+----+----------+------+------+ 
| id | t  | s1 | i1 | 
+----+----------+------+------+ 
| 1 | abc-2211 | abc | 2211 | 
| 2 | abc-21 | abc | 21 | 
| 3 | abc-32 | abc | 32 | 
| 4 | abc-9876 | abc | 9876 | 
+----+----------+------+------+ 
4 rows in set (0,00 sec) 

mysql>