2011-01-14 141 views
35

我有一個字段number,其類型爲varchar。即使它是varchar類型,它也會存儲具有可選前導零的整數值。排序按字典順序排列("42""9"之前)。如何通過數值進行訂購("9""42"之前)?在MySQL中對數字字段進行排序varcharchar

目前我使用的查詢:

SELECT * FROM table ORDER BY number ASC 
+1

`number`是一個字符串字段,對不對?因爲這是一個詞典排序。 – marcog 2011-01-14 00:26:13

+0

@marcog是不是一個int :) – wow 2011-01-14 00:35:09

+0

你應該只是改變列類型爲int並使用** zerofill **(如果你想保留00100) – ajreal 2011-01-14 06:02:48

回答

34

有幾個方法可以做到這一點:

  1. 並將其作爲數值而不是字符串。你已經打折了,因爲你想保持字符串像00100完整的前導零。
  2. 按字母順序排列爲數字。這將工作,但要意識到這是體面大小的數據庫的性能殺手。每行函數並不能很好地擴展。
  3. 添加第三列,它是字符串和索引的數字等價物。然後使用插入/更新觸發器,以確保每當字符串列更改時都能正確設置它。

由於絕大多數數據庫被讀取的次數遠多於寫入次數,因此上面的第三個選項將計算所有選擇的計算成本(在插入/更新時完成)。您的選擇將會非常快速,因爲它們使用數字列來排序(並且沒有每行功能)。

您的插入和更新速度會更慢,但這是您付出的代價,說實話,這是非常值得的。

觸發器的使用維護了表的ACID屬性,因爲兩列保留在步驟中。這是一個衆所周知的習慣用法,你通常可以在大多數性能優化中換取空間。

我們在很多情況下都使用過這種「技巧」,比如在原件旁邊存儲小寫版本的姓(而不是像tolower),識別字符串的長度以找到所有7個字符的用戶(而不是使用len)等等。

請記住,只要您瞭解(並減輕)後果,就可以從第三種標準形式恢復績效即可。

0

SELECT * FROM table ORDER BY number ASC

應該顯示您希望它顯示什麼..看起來像你的idnumber排序它在沒有被定義爲integer時刻。

+0

`1023198`將會是第一個 – wow 2011-01-14 00:24:30

+0

您是否將'number'字段設置爲int或者varchar? – 2011-01-14 00:26:58

+0

是的。它的varchar – wow 2011-01-14 00:29:56

54

試試這個

SELECT * FROM table_name ORDER BY CAST(field_name as SIGNED INTEGER) ASC 
15
SELECT * FROM table ORDER BY number + 0 
1

你可以在我的使用根據您的要求得到訂單下面的SQL查詢

SELECT * FROM mytable ORDER BY ABS(mycol) 
5

對於喜歡Er353,ER 280,ER 30,ER36值的表 默認的排序會給 ER280 ER30 ER353 ER36

select fieldname,substring(fieldname, 1, 2) as bcd, CONVERT(SUBSTRING(fieldname, 3, 9),UNSIGNED INTEGER) AS num from table_name order by bcd,num; 

的結果將在這個順序 ER30 ER36 ER280 ER353

12

招我剛剛學會。將'+0'添加到varchar字段順序子句中:

SELECT * FROM table ORDER BY number+0 ASC 

我現在在上面看到此答案。我想知道如果這是typecasting字段和整數。我沒有比較表現。工作很好。

24

其實我已經找到了一些有趣的事情:

SELECT * FROM mytable ORDER BY LPAD(lower(mycol), 10,0) DESC 

這可以讓你像訂購領域:

1 
2 
3 
10 
A 
A1 
B2 
10A 
111 
-3

粗糙,並準備:爲了1 * FIELD_NAME

1

給予包含VARCHAR的列username如下所示:

username1 
username10 
username100 

一個可以這樣做:

SELECT username, 
CONVERT(REPLACE(username, 'username', ''), UNSIGNED INTEGER) AS N 
FROM users u 
WHERE username LIKE 'username%' 
ORDER BY N; 

它並不便宜,但做這項工作。