如何在mySQL中按订单定义自定义订单

如何在mySQL中按订单定义自定义订单,mysql,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 结果应

在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等


这可能吗?

如果只有这三个值,那么您可以使用:

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

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

您现在有两个选择,第一个是将语言更改为ENUM(假设这是可能的),您只希望有一些变化

如果将其指定为ENUM'ENU'、'JPN'、'DAN',则顺序语言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

在性能方面,枚举方法将返回更快的结果,但如果需要添加更多语言,则会更麻烦。第三种选择是为这些语言添加一个规范化表,但在这种情况下,这可能会有些过分。

MySQL有一个名为的方便函数,非常适合这样的任务

按字段语言、'ENU'、'JPN'、'DAN',ID排序

然而,请注意

这会降低SQL的可移植性,因为其他DBMS可能没有这样的功能

当要排序的语言或其他值的列表变得越来越长时,最好有一个单独的带有sortorder列的表,并将其连接到查询中进行排序


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

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

如果有很多语言值,你可以有一个单独的表来存储每种语言,再加上一个排序顺序列并链接到该列,这将首先按ID排序,结果是a,b,c,d,e,F谢谢,这很好用-就像我接受的Mchl的答案一样,因为它看起来很简单谢谢,这非常适合我的情况,我只需要按两个值排序,一个是初级语言,例如JPN,一个是后备语言,例如ENU。伙计,你刚刚在magento中为我保存了一个重写:如果你以前有一个GROUP by怎么办?例如,我想要的第一个值出现在末尾?将带有GROUP BY的查询放在子查询中,并在外部queryNice中对其排序。我写了一个case order by子句,但是字段更紧凑,更容易重新排序。您在表定义中键入ENUM'ENU'、'JPN'、'DAN'?@pathros的确切位置,您将其指定为ENUM而不是VARCHAR等。MySQL在内部以特定顺序存储ENUM选项并对它们进行索引,所以,当按枚举列进行排序时,它将使用该内部索引而不是字符串值,除非使用CAST将其返回到varchar,否则不应结束DESC,而是结束CASE DESC,?no。并非所有案例都需要结束案例,这取决于上下文。过程中的CASE需要结束CASE,但是SELECT中的CASE不需要结束CASE,只需要结束-在本文中,它是一个控制流函数。
Project::find()
->orderBy([
    new Expression('FIELD(pid_is_t_m,2,0,1)'),
    'task_last_work'=> SORT_ASC
])->all();