2012-02-21 91 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