在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等。
这甚至可能吗?
答案 0 :(得分:241)
MySQL有一个名为FIELD()
的便捷功能,非常适合这样的任务。
ORDER BY FIELD(Language,'ENU','JPN','DAN'), ID
但请注意,
它使您的SQL不那么便携,因为其他DBMS可能没有这样的功能
当您的语言列表(或其他要排序的值)变得更长时,最好为它们设置一个带有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();