Pradeep Adiga の最初の提案、ORDER BY NEWID()
は正しく、私はこの理由で過去に使用したことがあります。
RAND()
の使用には注意が必要です。多くのコンテキストで、それは文ごとに 1 回のみ実行されるので、ORDER BY RAND()
は (各行で RAND() から同じ結果を得ているので) 何の効果も持ちません。
ORDER BY
節で使用される RAND()
でも同じことが起こることを示すために、次のように試してみました。
NEWID() が常に再評価されない場合、一意の識別子をキーとして 1 つの statemnt に多くの新しい行を挿入するときに UUID の目的が壊れてしまうので、NEWID()
による順序付けは機能します。
他の DBMS
上記は MSSQL (少なくとも 2005 と 2008、そして私の記憶が正しければ 2000 も) に当てはまります。 新しい UUID を返す関数は、すべての DBMS で毎回評価されるはずです NEWID() は MSSQL の下にありますが、ドキュメントまたは独自のテストによってこれを検証する価値があります。 RAND() のような他の任意結果関数の動作は、DBMS 間で異なる可能性が高いので、再度ドキュメントを確認してください。
また、DB が型に意味のない順序付けがないと仮定して、UUID 値による順序付けがいくつかのコンテキストで無視されるのを見たことがあります。 このような場合、順序付け句で UUID を文字列型に明示的にキャストするか、SQL Server の CHECKSUM()
のように他の関数をラップします (順序付けが 128 ビット値ではなく 32 ビット値で行われるため、これによっても若干のパフォーマンスの違いがあるかもしれませんが、最初に値ごとに CHECKSUM()
を実行するコストよりもそのメリットが大きいかどうかは、テストにお任せします。).
Side Note
任意の、しかしある程度繰り返し可能な順序付けが必要な場合、行自体のデータの比較的制御されていないサブセットによって順序付けを行います。 例えば、これらのどちらかは、任意の、しかし繰り返し可能な順序で名前を返します。
任意だが反復可能な順序は、アプリケーションではあまり有用ではありませんが、テストでは、さまざまな順序の結果でコードをテストしたいが、各実行を数回同じ方法で繰り返すことができるようにしたい場合に役立ちます (複数の実行で平均タイミング結果を取得したり、コードに行った修正で特定の入力結果セットによって以前に強調された問題や非効率性が取り除かれているかテストしたり、コードが「安定」で同じデータを特定の順序で送信すると毎回同じ結果を返せることをテストするだけ場合などです)。
このトリックは、本体内で NEWID() のような非決定的な呼び出しを許可しない関数から、より任意の結果を得るために使用することも可能です。 繰り返しますが、これは実世界で頻繁に使用されるものではありませんが、関数が何かランダムなものを返したい場合に便利で、「ランダムっぽい」のは十分です (ただし、ユーザー定義関数がいつ評価されるかを決めるルール、つまり、通常は行ごとに 1 回だけということを覚えておくように注意してください、さもなければ、結果は期待/要求したものではなくなります)。 数行以上の場合、要求された数の行が正しい順序で読み戻される前に、tempdbにスプールされた出力がほぼ確実に見られます。これは、たとえトップ10を探していたとしても、tempdbへの巨大な書き込みブロックとともに、完全なインデックススキャン(あるいはもっと悪いことにはテーブルスキャン)が発生するかもしれないことを意味します。 したがって、ほとんどのものと同様に、実稼働環境でこれを使用する前に、現実的なデータでベンチマークを行うことが非常に重要です。