2011-10-11 29 views
1

我有一個來自SQL字段的數據列表。我想根據字段ASC進行排序,但是當我這樣做時,它按錯誤的順序出現。我知道它爲什麼這樣做,但想知道是否有解決這個問題的解決方案。我聽說過natsort的php函數,但沒有調查過它。有沒有簡單的方法?按正確的順序排列mysql數字

學院

在10的藍

在10綠色

11以下的紅色

11以下的白

13歲以下的藍

13歲以下紅色

13歲以下的白

在14的藍

在15的藍

在15的紅色

下15的白色

下16's紅色

18歲以下藍色

18歲以下的紅色

在7的

在8位的紅

9歲的紅

+1

[自然排序MySQL](http://stackoverflow.com/questions/153633/natural-sort-in-mysql) – nobody

回答

3

有一個很簡單的方法來排序這個列表。對於開始UnderAcademy所有值執行基於以下順序排序算法BY子句:

ORDER BY 
REPLACE(Academy,'Under ','') + 0,Academy 

第一排序列基於去除串「下」,然後添加0這將強制結果整數的排序。

下面是「下」時除去第一計算所述數字值的示例:

mysql> select REPLACE('Under 15\'s Red','Under ','') + 0; 
+--------------------------------------------+ 
| REPLACE('Under 15\'s Red','Under ','') + 0 | 
+--------------------------------------------+ 
|           15 | 
+--------------------------------------------+ 
1 row in set (0.00 sec) 

第二次排序列將通過科學院的字符串值訂購。所有'Under 15's'被分組在一起並按字母數字排序。

下面是從問題的樣本數據加載到一個表,並進行排序:

mysql> use test 
Database changed 
mysql> drop table if exists under99color; 
Query OK, 0 rows affected (0.01 sec) 

mysql> create table under99color 
    -> (academy varchar(30), 
    -> id int not null auto_increment, 
    -> primary key (id), 
    -> index academy (academy)) engine=MyISAM; 
Query OK, 0 rows affected (0.04 sec) 

mysql> show create table under99color\G 
*************************** 1. row *************************** 
     Table: under99color 
Create Table: CREATE TABLE `under99color` (
    `academy` varchar(30) DEFAULT NULL, 
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`), 
    KEY `academy` (`academy`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 
1 row in set (0.00 sec) 

mysql> insert into under99color (academy) values 
    -> ('Under 10\'s Blue'),('Under 10\'s Green'),('Under 11\'s Red'), 
    -> ('Under 11\'s White'),('Under 13\'s Blue'),('Under 13\'s Red'), 
    -> ('Under 13\'s White'),('Under 14\'s Blue'),('Under 15\'s Blue'), 
    -> ('Under 15\'s Red'),('Under 15\'s White'),('Under 16\'s Red'), 
    -> ('Under 18\'s Blue'),('Under 18\'s Red'),('Under 7\'s'), 
    -> ('Under 8\'s Red'),('Under 9\`s Red'); 
Query OK, 17 rows affected (0.00 sec) 
Records: 17 Duplicates: 0 Warnings: 0 

mysql> select academy from under99color 
    -> ORDER BY REPLACE(Academy,'Under ','') + 0,Academy; 
+------------------+ 
| academy   | 
+------------------+ 
| Under 7's  | 
| Under 8's Red | 
| Under 9`s Red | 
| Under 10's Blue | 
| Under 10's Green | 
| Under 11's Red | 
| Under 11's White | 
| Under 13's Blue | 
| Under 13's Red | 
| Under 13's White | 
| Under 14's Blue | 
| Under 15's Blue | 
| Under 15's Red | 
| Under 15's White | 
| Under 16's Red | 
| Under 18's Blue | 
| Under 18's Red | 
+------------------+ 
17 rows in set (0.00 sec) 

mysql> 

試試看!

+0

可能的重複不知道表結構,只是提供單列。將主要文本剝離到預期編號的位置,並讓它提供結果的數字轉換值,這也是我在很多年前使用過的一種技巧。 – DRapp

+0

@DRapp - 一些技巧永遠不會消失。但是,根據生成的臨時表和實際表結構,此特技功能可能無法使用巨大的表。另一種方法是將計算的值存儲在表中並在ORDER BY中包含該數字列。通過計算值+ Acadmy列創建索引可以加速這樣的ORDER BY。 – RolandoMySQLDBA

+0

我完全同意,但同樣,根據您提供的內容以及知道真正瞭解要使用的表格的基礎結構的良好答案。 – DRapp

0

你的字段是字符串!因此它對字符串值進行排序。

0

它按字母順序排列;您需要解析輸出字段並在稍後根據數字對它們進行排序。

0

那麼,你可以分別存儲數量和顏色(可以選擇一個空白的顏色),然後按數字和顏色順序排列。 E.g:

SELECT CONCAT('Under ',ageIndex,'\'s ',colour) AS Team FROM Academy 
ORDER BY ageIndex, colour 

這樣做的可能的優勢,根據您的要求,就是你可以接着還對年齡和顏色運行查詢分開。

1

您可以將字段添加到選擇查詢中,該字段使用CAST將其置於數字中。首先,你必須想出一個子串方法,首先從字符串中選擇數字(也許在空間和''上使用Field函數)。一旦你把它作爲一個整數分離出來,那麼在那個時候排序應該是微不足道的。

可能的例子(僞碼 - 可能無法正常工作「開箱即用」):

SELECT TeamType, CAST(SUBSTRING(TeamType, FIELD(' ', TeamType), FIELD('\'', TeamType) - Field(' ', TeamType)), UNSIGNED) As TeamAge 
FROM Teams 
ORDER BY TeamAge, TeamType