Como definir uma ordem ORDER BY personalizada no mySQL

No MySQL, como defino uma ordem de sorting personalizada.

Para tentar explicar o que eu quero, considere esta tabela:

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

aqui eu quero retornar todas as linhas classificadas por Idioma e ID ascendente para que Language = ENU vem em primeiro lugar, então JPN e, por último, DAN.

O resultado deve ser: a, d, b, e, c, f etc.

Isso é possível?

O MySQL tem uma function útil chamada FIELD() que é excelente para tarefas como esta.

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

Note, no entanto, que

  1. Isso torna seu SQL menos portável, já que outros DBMSs podem não ter essa function

  2. Quando sua lista de idiomas (ou outros valores para classificar) ficar muito mais longa, é melhor ter uma tabela separada com uma coluna de ordem de sorting para eles e associá-la às suas consultas para pedidos.

Se esses são os únicos três valores, então você pode usar uma expressão CASE :

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

(Se poderia haver outros valores, talvez você queira adicionar alguma lógica extra para manter a ordenação consistente; por exemplo, você pode adicionar ELSE 4 a essa expressão CASE e, em seguida, ordenar pela própria Language como o terceiro critério de ordenação:

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

Você tem algumas opções de improviso, a primeira é mudar o idioma para ENUM (supondo que isso seja possível, e você só espera algumas variações)

Se você especificá-lo como ENUM('ENU','JPN','DAN') então ORDER Language ASC fará o pedido na ordem que você especificar.

O segundo envolverá um caso em algum lugar, ou seja,

 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 

Em termos de desempenho, o método ENUM retornará resultados mais rápidos, mas será mais incômodo se você precisar adicionar mais idiomas. Uma terceira opção seria adicionar uma tabela de normalização para os idiomas, o que pode ser um exagero nessa instância.