web-dev-qa-db-ja.com

mysqlのselectステートメント「in」句の値の順序で並べ替えます

整数のID値を持つ大きなテーブル(数百万行)からアカウントレコードのセットを選択しています。ある意味で、クエリの基本的なものです。私がやっていることは、大きなコンマ区切りのリストを作成し、それを「in」句としてクエリに渡すことです。現在、結果は完全に順序付けられていません。私がやりたいのは、「in」句の値の順序で結果を取得することです。

代わりに、一時テーブルを作成して結合を行う必要があると思います。これは避けたいのですが、できない場合があります。

考え?現在、クエリのサイズは、出力サイズを制限しようとしているため、それぞれ約60kに制限されていますが、任意に大きくなる可能性があります。これにより、実用的な観点から、「in」クエリが除外される可能性があります。物理的なもの。

前もって感謝します。

31
Kevin Galligan

実際には、これはより良いです:

SELECT * FROM your_table
WHERE id IN (5,2,6,8,12,1)
ORDER BY FIELD(id,5,2,6,8,12,1);

こちらがFIELDのドキュメントです。

http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_field

46
Dal Hundal

ちょっとしたコツ…。

SELECT * FROM your_table
WHERE id IN (5,2,6,8,12,1)
ORDER BY FIND_IN_SET(id,'5,2,6,8,12,1') DESC;

find_in_set内のIDのリストは文字列であるため、引用符で囲まれていることに注意してください。また、DESCがない場合、結果はリストで指定されたものとは逆の順序で返されることに注意してください。

4
Dal Hundal

クエリが60Kの場合、それは間違った方法で行っていることを示しています。

ORDER BY句を使用する以外に、結果セットを並べ替える方法はありません。 IN句のすべての要素を再度リストすることで、複雑なCASE句を注文に含めることができますが、クエリはおそらく120Kになります。

したくないことはわかっていますが、IN句の値をテーブルまたは一時テーブルに入れて結合する必要があります。一時テーブルにSortOrder列を含めて、それで並べ替えることもできます。結合のようなデータベース。このようにすると、クエリのパフォーマンスが向上します。

0
Mark Byers

最初のクエリは確かにorderby句を使用しています。したがって、結合を実行して、同じorderby句を使用することができます。

たとえば、これが最初のクエリだった場合

 SELECT customer_id 
 FROM customer 
 WHERE customer_id BETWEEN 1 AND 100 
 ORDER 
 BY last_name 

そしてこれはあなたの2番目のクエリでした

 SELECT Inventory_id 
 FROM Rentals 
 WHERE customer_id in(...注文リスト...)

組み合わせると

 SELECT r.inventory_id 
 FROM Rentals r 
 INNER 
 JOIN customer c 
 ON r.customer_id = c.customer_id 
 WHERE c.customer_id BETWEEN 1 AND 100 
 ORDER 
 BY c.last_name 
0
goat