如何在mySQL中定义自定义ORDER BY顺序

时间:2012-02-21 13:42:01

标签: mysql

在MySQL中如何定义自定义排序顺序。

试着解释一下我想要的内容:

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

这里我想返回按语言和升序ID排序的所有行,以便首先是Language = ENU,然后是JPN,最后是DAN。

结果应该是:a,d,b,e,c,f等。

这甚至可能吗?

4 个答案:

答案 0 :(得分:241)

MySQL有一个名为FIELD()的便捷功能,非常适合这样的任务。

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

但请注意,

  1. 它使您的SQL不那么便携,因为其他DBMS可能没有这样的功能

  2. 当您的语言列表(或其他要排序的值)变得更长时,最好为它们设置一个带有sortorder列的单独表,并将其连接到您的查询以进行排序。

    < / LI>

答案 1 :(得分:43)

如果这些是唯一的三个值,那么您可以使用a CASE expression

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

(如果可能有其他值,那么您可能需要添加一些额外的逻辑以保持顺序一致;例如,您可以将ELSE 4添加到该CASE表达式,然后按顺序排序Language本身作为第三个排序标准:

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

答案 2 :(得分:17)

你手边有几个选项,第一个是将语言改为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方法将返回更快的结果,但如果您需要添加更多语言则会更麻烦。第三种选择是为语言添加一个规范化表,但在这种情况下这可能是过度的。

答案 3 :(得分:2)

对于Yii2框架,我们可以通过以下方式实现

Project::find()
->orderBy([new Expression('FIELD(pid_is_t_m,2,0,1)'),'task_last_work'=> SORT_ASC])
->all();