2012-02-21 60 views
88

在MySQL中,我該如何定義一個自定義排序順序。如何在mySQL中定義一個自定義ORDER BY訂單

試圖解釋我要考慮這個表的內容:

ID Language Text 
0 ENU   a 
0 JPN   b 
0 DAN   c  
1 ENU   d 
1 JPN   e 
1 DAN   f 
2 etc... 

這裏我想回到按語言和上升ID排序的所有行,以便語言= ENU至上,那麼JPN,最後DAN。

結果應該是:一,d,B,E,C,F等

這甚至可能嗎?

回答

195

MySQL有一個方便的功能,稱爲FIELD(),這是非常適合這樣的任務。然而

ORDER BY FIELD(Language,'ENU','JPN','DAN'), ID

注意,那

  1. 它使你的SQL移植性較差,因爲其他DBMS可能不具備這樣的功能

  2. 當你的語言(或其他值列表排序)得到更長的時間,最好有一個單獨的表與sortorder列他們,並加入到您的查詢排序。

+2

非常感謝這是我的情況,我只需要通過兩個值(一種主要語言,例如JPN和一種後備語言,例如ENU)進行排序。 – Muleskinner 2012-02-21 14:11:27

+1

你剛剛救了我一個重寫在magento :) :) – 2015-02-06 15:18:07

+1

如果你有一個'GROUP BY'之前?例如,我想要的第一個值出現在最後? – Pathros 2015-03-25 18:51:58

31

如果這些是僅有的三個值,那麼你可以使用a CASE expression

ORDER BY `ID`, 
     CASE `Language` 
     WHEN 'ENU' THEN 1 
     WHEN 'JPN' THEN 2 
     WHEN 'DAN' THEN 3 
     END 

(如果有可能是其它的值,那麼你可能需要添加一些額外的邏輯,以保持順序保持一致;例如,你可能會Language自身添加ELSE 4CASE表達,然後才能作爲第三排序標準:

ORDER BY `ID`, 
     CASE `Language` 
     WHEN 'ENU' THEN 1 
     WHEN 'JPN' THEN 2 
     WHEN 'DAN' THEN 3 
     ELSE 4 
     END, 
     `Language` 
) 
+1

如果有很多語言值,你可以有一個單獨的表格存儲每種語言加上一個排序順序列,並鏈接到該 – kaj 2012-02-21 13:45:47

+0

這將按ID先排序,產生a,b,c,d,e ,f – piotrm 2012-02-21 13:56:34

+0

非常感謝這個作品 - 我接受Mchl答案,因爲它看起來更簡單 – Muleskinner 2012-02-21 14:02:42

13

你有幾個選項副手,第一是要改變語言成爲ENUM(假設這是可能的,並且您只希望有一些變化)

如果您將它指定爲ENUM('ENU','JPN','DAN')那麼ORDER Language ASC將按您指定的順序排序。

第二個將涉及地方的情況下,即

SELECT * FROM table 
ORDER BY CASE Language 
    WHEN 'ENU' THEN 3 
    WHEN 'JPN' THEN 2 
    WHEN 'DAN' THEN 1 
    ELSE 0 
END DESC, ID ASC 

性能方面的ENUM方法將返回更快的結果,但如果你需要添加更多的語言是更多的麻煩。第三種選擇是爲語言添加規範化表,但在這種情況下可能會過度。

+0

你究竟在哪裏輸入'ENUM('ENU','JPN','DAN')'? – Pathros 2015-03-25 18:52:46

+1

@pathros在表定義中,您將其指定爲ENUM而不是VARCHAR等。內部MySQL按照特定順序存儲ENUM選項併爲它們編制索引,因此,當通過ENUM列進行排序時,它將使用該內部索引而不是字符串值(除非使用CAST()使其恢復爲VARCHAR) – 2015-03-26 09:36:38

+0

不應該'END DESC','END CASE DESC','? – 2017-11-10 14:11:01