mySQLでカスタムORDER BY順序を定義する方法


142

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などになります。

これは可能ですか?

回答:


275

MySQLには、FIELD()このようなタスクに最適な便利な関数があります。

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

ただし、

  1. 他のDBMSにはそのような機能がない可能性があるため、SQLの移植性が低下します

  2. 言語のリスト(またはその他のソート値)がはるかに長くなる場合は、それらのsortorder列を備えた別のテーブルを用意し、それをクエリに結合して並べ替えることをお勧めします。


3
これは、2つの値(JPNなどの主要言語とENUなどのフォールバック言語)で並べ替える必要がある私の状況に完全に感謝します。
Muleskinner 2012

4
magentoでの書き換えを保存したばかりの男:)
Erik Simonic、2015

1
GROUP BY前に持っている場合はどうなりますか?たとえば、最初に必要な値が最後に表示されますか?
Pathros 2015年

クエリをGROUP BYサブクエリに入れて、外部クエリで
並べ替え

1
魅力のように働く:)
Brane

53

これらが3つの値のみの場合CASEを使用できます。

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

(他の値が存在する可能性がある場合は、順序を一貫させるためにいくつかの追加のロジックを追加ELSE 4することができます。たとえば、そのCASE式に追加してLanguage、3番目の順序付け基準としてそれ自体で順序付けすることができます。

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


1
そして、多くの言語値がある場合は、各言語とソート
順列を

1
これは最初にIDで
順序付け

これは完全に機能します-単純に見えるので、私が受け入れたMchlが答えたように
Muleskinner

19

いくつかのオプションがありますが、1つ目は、言語をENUMに変更することです(これが可能であり、いくつかのバリエーションしか期待できない場合)。

あなたはそれを指定した場合などENUM('ENU','JPN','DAN')、その後ORDER Language ASC、指定した順番で注文します。

2つ目は、どこかのケースに関係します。

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番目のオプションは、言語の正規化テーブルを追加することですが、この場合はやりすぎかもしれません。


正確にどこに入力しますENUM('ENU','JPN','DAN')か?
Pathros 2015年

1
テーブル定義の@pathrosでは、VARCHARなどではなくENUMとして指定します。内部的にMySQLはENUMオプションを特定の順序で格納し、それらにインデックスを付けます。そのため、ENUMカラムで具体的に順序付けするときは、その代わりにその内部インデックスを使用します。文字列値(VARCHARに戻すためにCAST()が使用されている場合を除く)
My School PortalのSimon

すべきではEND DESC,ないEND CASE DESC,
Istiaque Ahmed 2017

いいえ。すべてCASEが必要というわけではありませんEND CASE。それはコンテキストに依存しています。 CASE手順内ではrequire END CASEdev.mysql.com/doc/refman/5.5/en/case.html)がCASE必要ですがEND CASE、SELECT内では単純にENDdev.mysql.com/doc/refman/5.7/en/… )が必要です-これでコンテキストこれは制御フロー関数です。
マイスクールポータルでのサイモン

1

Yii2フレームワークの場合、次の方法で実現します

Project::find()
->orderBy([new Expression('FIELD(pid_is_t_m,2,0,1)'),'task_last_work'=> SORT_ASC])
->all();
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.