質問
を申請するには、どうしたらいいランダム行(若しくは真にランダムとしての可能)純SQL?
解決
こんにちは: SQLを選択し、ランダム行からデータベースのテーブル.これを行うためのメソッドをこのMySQL、PostgreSQL、Microsoft SQL Server、IBM DB2、Oracleることができるのでコピーからのリンク):
選択ランダム行MySQL:
SELECT column FROM table
ORDER BY RAND()
LIMIT 1
選択ランダム行PostgreSQL:
SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1
選択ランダム行Microsoft SQLサーバー:
SELECT TOP 1 column FROM table
ORDER BY NEWID()
選択ランダム行IBM DB2
SELECT column, RAND() as IDX
FROM table
ORDER BY IDX FETCH FIRST 1 ROWS ONLY
選択ランダムに登録Oracle:
SELECT column FROM
( SELECT column FROM table
ORDER BY dbms_random.value )
WHERE rownum = 1
他のヒント
のようにソリューションJeremies:
SELECT * FROM table ORDER BY RAND() LIMIT 1
作業が必要な一連のスキャンのすべてのテーブルが実際に近いものであるかどうかをランダム値はそれぞれの行のニーズを演算することができますので、最小で決定できる非常に遅いためにも中規模ます。私の勧告に使うか指数値の列の多くのテーブルにこれらの主キー)を押し書きのようなもの:
SELECT * FROM table WHERE num_value >= RAND() *
( SELECT MAX (num_value ) FROM table )
ORDER BY num_value LIMIT 1
この作品を数時間にかかわらず、テーブルサイズの場合 num_value
はインデックス付き一点に注意:こ num_value
は同等の範囲に分布して 0..MAX(num_value)
.場合データセットを強力に脱し、この仮定を取得しま斜めに結果(一部の行表示ができるようでした。
わからない効率的なことですが、私は使用する前に:
SELECT TOP 1 * FROM MyTable ORDER BY newid()
で、特別な技術を必要とか、ランダムに発注を意味するランダムです。
ORDER BY NEWID()
か 7.4 milliseconds
WHERE num_value >= RAND() * (SELECT MAX(num_value) FROM table)
か 0.0065 milliseconds
!
まけるなら間違いなく後者の方法です。
でしょうかんサーバーだ。古いバージョンのSQLサーバーご利用いただくことができ:
select top 1 * from mytable order by newid()
SQL Server2005年までと、ご利用 TABLESAMPLE
をランダムサンプルの再現性:
SELECT FirstName, LastName
FROM Contact
TABLESAMPLE (1 ROWS) ;
SQLサーバー
newid()を確認するためによりますが、非常に高価な大型結果セットで形成されるid毎の列を並べ替えます。
TABLESAMPLE()が良いパフォーマンスの観点からは、ものを取得しまclumpingの結果すべての行のページが返されます).
より良い舞台真ランダムサンプルの最良の方法はフィルタリ行列れる。また、以下のコードサンプルのSQLサーバーの書籍をオンライン記事 限定結果セットを使用TABLESAMPLE:
またランダムなサンプルの 個人、行の変更がクエリー フィルタ行列をランダムではなく、 使用TABLESAMPLE.例えば、 以下のクエリを使用しNEWID 機能に戻約 %の行の 売りです。SalesOrderDetailテーブル:
SELECT * FROM Sales.SalesOrderDetail WHERE 0.01 >= CAST(CHECKSUM(NEWID(),SalesOrderID) & 0x7fffffff AS float) / CAST (0x7fffffff AS int)
のSalesOrderID列が含まれて のチェックサム表現で NEWID()を評価した行 をサンプリング単列ます。式のキャスト(チェックサム(NEWID(), SalesOrderID)&0x7fffffffとしてfloat/ キャスト(0x7fffffffとしてint)に評価し ランダムなfloat値が0-1.
実行をテーブル1,000,000行が、ここが私の成果:
SET STATISTICS TIME ON
SET STATISTICS IO ON
/* newid()
rows returned: 10000
logical reads: 3359
CPU time: 3312 ms
elapsed time = 3359 ms
*/
SELECT TOP 1 PERCENT Number
FROM Numbers
ORDER BY newid()
/* TABLESAMPLE
rows returned: 9269 (varies)
logical reads: 32
CPU time: 0 ms
elapsed time: 5 ms
*/
SELECT Number
FROM Numbers
TABLESAMPLE (1 PERCENT)
/* Filter
rows returned: 9994 (varies)
logical reads: 3359
CPU time: 641 ms
elapsed time: 627 ms
*/
SELECT Number
FROM Numbers
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), Number) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
場合に逃げることができ用TABLESAMPLEますので最高の性能を実現できます。その他のnewid()/フィルター方法。newid()を確認するためにすべき最後の場合は大きくする事ができません。
可能な場合は、使用保存書を避けるため非効率性の双方を指標RND()をレコード番号ます。
PREPARE RandomRecord FROM "SELECT * FROM table LIMIT ?,1"; SET @n=FLOOR(RAND()*(SELECT COUNT(*) FROM table)); EXECUTE RandomRecord USING @n;
るという方向けのランダム値を新しいカラムだけでその目的は、このようになっ(pseudeコード+SQL):
randomNo = random()
execSql("SELECT TOP 1 * FROM MyTable WHERE MyTable.Randomness > $randomNo")
この採用により、MediaWikiのコードです。もちろん、バイアスに対し小さい値であることを見出したのに十分なラップのランダムな値をゼロにない場合の行をフェッチされる.
newid()解決を必要とする全テーブルスキャンのそれぞれの行に割り当てることができる新しいことで、少ないperformant.
rand()溶液に動作しない場合があり全(すなわちと指定)での機能評価を行うだけで、一度 毎 列が割り当てと同じ"ランダム"。
SQL Server2005 2008年にしていくために、どのようなランダムなサンプルの各行から 書籍のオンライン):
SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), SalesOrderID) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
Instedの 使用RAND()ではなく, まだ最大ID=Max):
SELECT MAX(ID) FROM TABLE;
を取得しランダム1..Max(=My_Generated_Random)
My_Generated_Random = rand_in_your_programming_lang_function(1..Max);
そしてこのSQL:
SELECT ID FROM TABLE WHERE ID >= My_Generated_Random ORDER BY ID LIMIT 1
注その他の行するId等以上の選ばれた値です。を取得することも可能で狩りの行はテーブル、同等以下のIDをMy_Generated_Random変更し、クエリのようになります:
SELECT ID FROM TABLE WHERE ID <= My_Generated_Random ORDER BY ID DESC LIMIT 1
指摘されているように、@BillKarwinのコメント@cnuの答...
と組み合わせる場合、制限がその場で発音を確認することがで行い(少なくともPostgreSQL9.1)とランダムな順序ではなく直接の実行例えば
SELECT * FROM tbl_post AS t
JOIN ...
JOIN ( SELECT id, CAST(-2147483648 * RANDOM() AS integer) AS rand
FROM tbl_post
WHERE create_time >= 1349928000
) r ON r.id = t.id
WHERE create_time >= 1349928000 AND ...
ORDER BY r.rand
LIMIT 100
だけのように"r"を生成する'ランドの価値らゆるキー値の複雑なクエリで参加でも制限された行数'r'が可能です。
のキャストして整数とPostgreSQL9.2る特定の並べ替え最適化のための整数、単精度浮動小数種類です。
一番のソリューションやこちらを避ける選別が必要な一連のスキャンに渡ります。
もあるような一連のスキャンへの切替えによるインデックススキャン.がわかっている場合は、それを指数値の乱数列を得ることができ、結果とほぼinstantially.問題はどのように、指数値のこと。
以下のソリューションでは、PostgreSQL8.4:
explain analyze select * from cms_refs where rec_id in
(select (random()*(select last_value from cms_refs_rec_id_seq))::bigint
from generate_series(1,10))
limit 1;
私は上記溶液で10種ランダム指数値範囲は0..[最終値のid"となります。
の10数は任意に使用100 1000としてでもないのに大きな影響を及ぼの応答時間が実現されています。
その問題を使用してください疎id しょう逃.このセクション バックアッププラン :)この場合、純粋な古い順にランダム()を返します。組み合わせidは以下のようなものです:
explain analyze select * from cms_refs where rec_id in
(select (random()*(select last_value from cms_refs_rec_id_seq))::bigint
from generate_series(1,10))
union all (select * from cms_refs order by random() limit 1)
limit 1;
ないの 組合 すべての を提供しています。この場合は最初の部分を返しますデータのない実行されます。
下旬にはもってここでは、その子孫んを追加。
もう一つのアプローチではトップを回し、交番です。わからない場合は"純粋なSQL"で使用可変にすることが明らかにSQL Server2008年.以下に例を示しますい使用に対するテーブルの辞書の言葉をしたい場合はランダムます。
SELECT TOP 1
word
FROM (
SELECT TOP(@idx)
word
FROM
dbo.DictionaryAbridged WITH(NOLOCK)
ORDER BY
word DESC
) AS D
ORDER BY
word ASC
もちろん、@idxはランダムに生成される整数の範囲は1からCOUNT(*)は、ターゲットテーブル,幅広く.ばカラムがインデックス,すぐの恩恵を享受することになる。もう一つのメリットには、利用できる機能でNEWID()を許可しない.
最後に、上記のクエリの実行の約1/10のexec時間のNEWID()タイプのクエリの同じテーブル。YYMV.
また、使ってみ new id()
機能です。
だけを書検索-利用の注文 new id()
機能です。でもかせとなります。
のためのMySQLの取得ランダム記録
SELECT name
FROM random AS r1 JOIN
(SELECT (RAND() *
(SELECT MAX(id)
FROM random)) AS id)
AS r2
WHERE r1.id >= r2.id
ORDER BY r1.id ASC
LIMIT 1
かったことに答えていない。私は追加の制約し、必要なら初期種を選択でき、同一の行のセット。
MS SQL:
最小例:
select top 10 percent *
from table_name
order by rand(checksum(*))
標準化実施時間:1.00
NewId()例:
select top 10 percent *
from table_name
order by newid()
標準化実施時間:1.02
NewId()
はinsignificantlyより遅くな rand(checksum(*))
, できない場合に使いたいと大きを記録する。
選択種の利用が重要であると考えられ:
declare @seed int
set @seed = Year(getdate()) * month(getdate()) /* any other initial seed here */
select top 10 percent *
from table_name
order by rand(checksum(*) % seed) /* any other math function here */
の場合を選択する必要があると同定され、種こう。
に指定(動作確認11.0.5569)
SELECT TOP 100 * FROM employee ORDER BY CRYPT_GEN_RANDOM(10)
がく
SELECT TOP 100 * FROM employee ORDER BY NEWID()
SQLサーバーを組み合わせることができTABLESAMPLEとNEWID()を取得しても良いランダムネスがそのまま残されています。することができればだいたい1、または少数の並列する。
SELECT TOP 1 * FROM [table]
TABLESAMPLE (500 ROWS)
ORDER BY NEWID()
SELECT * FROM table ORDER BY RAND() LIMIT 1
してくださいCD-男:を"ORDER BY RAND()は"働くために小さなテーブルがなさんのみを選択しました。
また、"num_value>=RAND()*..."技いていきたいと思っておりますってランダムな結果を持っていた"ランダムに"カラムのテーブル更新しまい、ふらつきなどがあらわれです。このシングル更新を実行してください(特にがんにおいてインデックスこのコーナー)でよりはるかに早く作成乱数、各列の選択が実行されます。
できTableSampleなっ戻りランダムなサンプルに表示されません。で演出します検索すると見ランダムなサンプルの8KBのページはどのくらいですか。そして、自分のクエリを実行に対するデータに含まれるページ。いかにデータグループ化されウェブサイト上に掲載され(挿入順等)、このデータだけるように、実際にランダムなサンプルです。
参照: http://www.mssqltips.com/tip.asp?tip=1308
このMSDNのページをTableSampleを含む方法について、以下に例を示をactualyのランダムサンプルデータです。
このアイデアの上場が順序付け
ただし、ご利用の場合は一時テーブルで割り当てるランダム指数(のように多くのソリューションを提案)、鷲掴み、一つ以上の任意の番号0-1.
例えば、(DB2):
WITH TEMP AS (
SELECT COMLUMN, RAND() AS IDX FROM TABLE)
SELECT COLUMN FROM TABLE WHERE IDX > .5
FETCH FIRST 1 ROW ONLY
シンプルで効率的な方法から http://akinas.com/pages/en/blog/mysql_random_row/
SET @i = (SELECT FLOOR(RAND() * COUNT(*)) FROM table); PREPARE get_stmt FROM 'SELECT * FROM table LIMIT ?, 1'; EXECUTE get_stmt USING @i;
あのシーンをオラクルの代わりにdbms_random.価値があり、フルスキャン順に行によるdbms_random.値では非常に遅いため大きます。
この代わり:
SELECT *
FROM employee sample(1)
WHERE rownum=1
のためのFirebird:
Select FIRST 1 column from table ORDER BY RAND()
SQL Server2012+を使用できます オフセットを取得すクエリー このためには、単一のランダム行
select * from MyTable ORDER BY id OFFSET n ROW FETCH NEXT 1 ROWS ONLY
について、以下の情報を出力するアイデンティティカラムを行いたい計算したとして乱数0count()-1のテーブル(オフセット0は最初の行のすべて)
この作品は穴のテーブルデータなどのインデックス作業のために提供しています。そのための非常に良いる乱数の発生源として作業をする自分を通過するものnigglesその他の方法ではない。また、性能できるのはとても良いし、小さなデータセットでしてがんになった深刻な性能試験対数百万円とされています。
のためのSQL Server2005年以上の延長@GreyPantherの答えの場合 num_value
は連続的な値です。この作品を過ぎた場合またはいない均一に分散データセットが num_value
ではない番号が独自の識別子です。
WITH CTE_Table (SelRow, num_value)
AS
(
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS SelRow, num_value FROM table
)
SELECT * FROM table Where num_value = (
SELECT TOP 1 num_value FROM CTE_Table WHERE SelRow >= RAND() * (SELECT MAX(SelRow) FROM CTE_Table)
)
ランダム関数のsqlできます。まだ限界で一列だけで追加すること。
SELECT column FROM table
ORDER BY RAND()
LIMIT 1