_ORDER BY
_句の仕組みとFIELD()
関数の仕組みを理解しています。私が理解したいのは、両者がどのように連携してソートするかです。行はどのように取得され、ソート順はどのように導出されますか
_+----+---------+
| id | name |
+----+---------+
| 1 | stan |
| 2 | kyle |
| 3 | kenny |
| 4 | cartman |
+----+---------+
SELECT * FROM mytable WHERE id IN (3,2,1,4) ORDER BY FIELD(id,3,2,1,4)
_
上記のクエリは、
_+----+---------+
| id | name |
+----+---------+
| 3 | kenny |
| 2 | kyle |
| 1 | stan |
| 4 | cartman |
+----+---------+
_
oRDER BY 3、2、1、4と同じようなもの
質問
記録のために
_SELECT * FROM mytable WHERE id IN (1,2,3,4) ORDER BY FIELD(id,3,2,1,4);
_
WHERE
句でリストを並べる必要がないため、同様に機能するはずです。
それがどのように機能するかについては、
FIELD() は、検索する値が存在する場合に、コンマ区切りリストのインデックス位置を返す関数です。
_ORDER BY
_の値は、 FIELD() が返すものによって評価されます
あらゆる種類の派手な注文を作成できます
たとえば、 IF() 関数を使用すると、
_SELECT * FROM mytable
WHERE id IN (1,2,3,4)
ORDER BY IF(FIELD(id,3,2,1,4)=0,1,0),FIELD(id,3,2,1,4);
_
これにより、最初の4つのIDがリストの上部に表示されます。それ以外の場合は、下部に表示されます。どうして?
_ORDER BY
_では、0または1を取得します。
最初の列をDESCで反転させましょう
_SELECT * FROM mytable
WHERE id IN (1,2,3,4)
ORDER BY IF(FIELD(id,3,2,1,4)=0,1,0) DESC,FIELD(id,3,2,1,4);
_
_ORDER BY
_では、0または1を取得します。
これについて内部的に知りたい場合は、本の pages 189 and 192に進んでください
本当の深いダイビングのために。
本質的には、_ORDER *order
_(_ORDER BY
_式ツリー)というC++クラスがあります。 _JOIN::prepare
_では、_*order
_はsetup_order()
という関数で使用されます。なぜJOIN
クラスの真ん中にあるのですか? すべてのクエリ、単一のテーブルに対するクエリであっても、常にJOINとして処理されます(私の投稿を参照 JOIN条件とWHERE条件の間に実行の違いはありますか? ? )
これらすべてのソースコードは_sql/sql_select.cc
_です。
明らかに、_ORDER BY
_ツリーはFIELD(id,3,2,1,4)
の評価を保持します。したがって、数値0、1、2、3、4は、関係する行への参照を保持しながらソートされる値です。
多分これは実際のコードから遠すぎるので、あなたが望むものから十分に低いレベルではありません:
MySQLがインデックスを使用してソートされた順序でデータを取得できない場合、選択されたすべての列といくつかの追加データを含む一時テーブル/結果セットを作成します-それらの1つは、各行のORDER BY式値の結果を格納するためのある種の列です-次に、このtmpテーブルを「filesort」ルーティンに送信し、どの列でソートするかを指定します。その後、行はソートされた順序になっているので、行を1つずつ選択して、選択した列を返すことができます。