2012-12-18 133 views
3

我已經搜索了一個方法來將字符串排序爲mysql中的數字。mysql order string as number

我行是這樣的:

order_column在MySQL的此列

1.1.2 
1.1.100 
1.1.1 

訂貨上升會產生:

1.1.1 
1.1.100 
1.1.2 

我很感興趣,得到以下結果:

1.1.1 
1.1.2 
1.1.100 

有沒有辦法使用SQL來產生這個結果?我的專欄的

其他可能的值:

28.1999.1.1 
1 
1.1.154.20 
100.1.1.1.1.15 

謝謝,我很感激大家的時間。

編輯: Fast Relational method of storing tree data (for instance threaded comments on articles) 看一看Ayman Hourieh的第一個答案。我正在嘗試解決這個問題。我的網站有每篇文章不超過10K的意見,所以我發現了一個變通辦法是這樣的:

000001 
000002 
000002.000001 
000002.000001.000001 
000002.000002 
000002.000003 
000003 

基本上,把零我的評論櫃檯前讓字符串比較不會失敗。但這隻會對99999評論有用。我可以添加更多的零,可以說10個零,並且可以用於999999999評論,但我希望能有一個更優雅的解決方案。

回答

0

創建一個與此列等同的新列,並用字符串替換'。'。與''(無)。將這個新字段存儲爲一個數字。按此字段排序而不是在您的查詢中。

如果你不能添加一個新的列到表中,你可以在PHP等處理這個,以達到相同的效果,例如在網站上的顯示目的。

http://php.net/manual/en/function.str-replace.php 
+0

如果我替換'。'沒有任何東西,那麼1.11將等於11.1和1.1.1 – nookie

+0

好的,你可以將1.1.1分成三列,然後你需要按1,2,3列排序,並在你的語句中使用group。 – ChelseaStats

3

如果字符串不是太長,你可以做

ORDER BY cast(replace(your_column_name,'.','') as unsigned); 
+0

很好...但是,如果列值是1.2.1.1和1.1.1.100,那麼命令將是錯誤的,我認爲... –

+0

@mhasan:查詢給出了問題所述的所需輸出:'1.1.1 1.1.2 ,1.1.100'。我不確定'1.2.1.1,1.1.1.100'的'正確'順序是什麼。沒有給出額外的細節,我假設在刪除「。」後將字符串視爲整數。...... – a1ex07

+0

如果將有兩個值:'28 .1999.1.1'和'2819.99.1.1',該怎麼辦? – Devart

0

你可以使用在你的:)

以下SQL

SELECT REPLACE(column_name,'.','') AS column_name1 FROM table_name ORDER BY column_name1; 
1
SELECT INET_ATON('10.0.5.9'); 

試試這個功能也許這不是一種替代方案,因爲它僅適用於IP地址t YPE。而且你的IP地址有更多的部分。

+0

這對那些不是IP地址的字符串有效嗎?給出的例子不是。 – Cylindric

+0

@Cylindric是的,只是注意到;)只有我希望如果我們有這樣的功能超出IP地址排序 – bonCodigo

0

如果你是最後一位組排序,然後

SELECT CAST(MID(order_column, 
CHAR_LENGTH(order_column) - 
LOCATE('.',REVERSE(order_column))+2) AS DECIMAL) AS order_column_as_number 
FROM thetable 
ORDER BY order_column_as_number 

似乎工作。

如果存在沒有'。'的字符串,根本不起作用。在他們中,如果你想要由其他組織來定購,你將不得不提取更多的部件以進行排序,但如果你真的只想在sql中完成,這可能是一個開始。

+0

它不只是最後一個數字組。它看起來更像是「按第一組排序,然後是第二組,然後是第三組」,等等。 – Cylindric

+0

另外它不包含'。'的示例。我想人們可以通過這種方式提取更多東西來訂購,但它會很快變得凌亂。 – Ledhund

0

確保您的這些數字的列是INT而不是varchar。

如果使用VARCHAR你的專欄將通過那些誰擁有1先等等進行排序...

+0

不要做任何額外的代碼,只是做我告訴過你的,把這些數字的列改爲'INT'而不是char或varchar –

1

這不會是有效的,並且可以清理,但對於如何做一個想法這個。它依賴於表稱爲整數以0至9

SELECT somefield , SUM(POW(100, occurrences - anInteger) * somefield_split) OrderField 
FROM 
    (SELECT id,anInteger, somefield, SUBSTRING_INDEX(SUBSTRING_INDEX(somefield, ".", anInteger), ".", -1) AS somefield_split, LENGTH(somefield) - LENGTH(REPLACE(somefield, '.', '')) + 1 AS occurrences 
    FROM splittertest, (SELECT a.i*10+b.i AS anInteger FROM integers a, integers b) Sub1 
    HAVING occurrences >= anInteger) Sub2 
GROUP BY somefield 
ORDER BY somefield, OrderField 

稱爲I 10行與值的單個柱思想是子選擇得到一個範圍從0號到99和分割了繩子關閉點基於此的分離值。它獲得特定字符串中的點數。然後它將字符串的每一位乘以100的總功率減去此節的數量,並在此基礎上求和。

因此5.10.15被分成5,10和15.有3個部分,所以第一部分乘以100乘以(3-0)的冪,第二部分乘以100乘以(2 - 0)等。

如果點數變化(即點數總是較大的點),這會產生奇怪的結果,但這可以通過使用任意行上的最大點數來固定找出能力,而不是特定線上的點數。

祝你好運!

2

您將無法有效地做到這一點,因爲這將錯過所有索引,但如果它是一個一次性的,這會工作。可悲的是,由於MySQL無法(我知道)一次替換多個字符,它看起來很可怕。

SELECT value FROM TEST ORDER BY 
    REPLACE(
    REPLACE(
     REPLACE(
     REPLACE(
      REPLACE(
      REPLACE(
       REPLACE(
       REPLACE(
        REPLACE(value, 
        '1', '0'), 
        '2', '0'), 
       '3', '0'), 
       '4', '0'), 
      '5', '0'), 
      '6', '0'), 
     '7', '0'), 
     '8', '0'), 
    '9', '0'),value; 

它基本上會用0代替所有數字,然後按順序先代替。由於.在0之前的順序,它將正確按數字組排序。完成後,按值排序,因爲任何具有相同數字組的值應按正確的順序排序。

爲了使效率更高,您可以將替換後的值作爲列存儲在數據庫中,以便爲其編制索引。

SQLfiddle demo here