3

0 から行数までの範囲のランダムな列のすべての行を入力しようとしています。これまでのところ、私はこれを持っています

UPDATE table
SET column = ABS (RANDOM() % (SELECT COUNT(id) FROM table))

これは仕事をしますが、重複した値が生成され、悪いことが判明しました。Unique 制約を追加しましたが、クラッシュするだけです。

特定の範囲からのランダムな一意の値で列を更新する方法はありますか?

ありがとう!

4

2 に答える 2

2

後でランダムな順序でレコードを読み取りたい場合は、その時点で順序付けを行うことができます。

SELECT * FROM MyTable ORDER BY random()

(複数のクエリで同じ順序が必要な場合、これは機能しません。)


rowidそれ以外の場合は、一時テーブルを使用して、テーブルの と数字 1..N の間のランダム マッピングを格納できます。(これらの番号はrowid、一時テーブルの によって自動的に生成されます。)

CREATE TEMP TABLE MyOrder AS
  SELECT rowid AS original_rowid
  FROM MyTable
  ORDER BY random();
UPDATE MyTable
  SET MyColumn = (SELECT rowid
                  FROM MyOrder
                  WHERE original_rowid = MyTable.rowid) - 1;
DROP TABLE MyOrder;
于 2012-12-15T22:19:45.393 に答える
1

あなたが探しているように見えるのは、単なる乱数のセットではなく、数値 1..N のランダムな順列です。これは難しいです。Knuth (The Art of Computer Programming) または Bentley (Programming Pearls または More Programming Pearls) を見ると、推奨される方法の 1 つは、値 1..N で配列を作成し、各位置で現在の値を交換することです。配列からランダムに選択された他の値を持つ値。(配列内の任意の位置であるか、配列内で値が続くだけであるかを確認するために、本を掘り下げる必要があります。)コンテキストでは、この順列を下のテーブルの行に適用しますいくつかの順序付け、したがって、順序付けの下の行 1 は、位置 1 の配列の値を取得します (1 ベースのインデックスを使用)、など。

Programming Pearls の第 1 版、Column 11 Searching で、Bentley は次のように述べています。

セクション 3.4.2 の Knuth のアルゴリズム P は、配列 X[1..N] をシャッフルします。

for I := 1 to N do
    Swap(X[I], X[RandInt(I,N)])

ここで、RandInt(n,m)関数は範囲 [n..m] (両端を含む) のランダムな整数を返します。簡潔でないとしても、それは何もありません。

別の方法は、更新する値が 1 つ残っているときにコードをスラッシングし、乱数ジェネレーターがまだ使用されていない値を 1 つ選択するまで待機することです。ヒット アンド ミス プロセスとして、特に合計行数が多い場合は、時間がかかることがあります。

それを実際に SQLite に変換するのは別の課題です。あなたのテーブルはどれくらいの大きさですか?便利な一意のキーはありますか (ランダム化しているもの以外)?


主キーがあれば、各主キーに 1 から N の範囲の数値が割り当てられるような構造の配列を簡単に生成できます。次に、アルゴリズム P を使用して数値を並べ替えます。次に、適切な乱数を使用して主キーからテーブルを更新できます。SQLite が 2 つのテーブル間の結合を伴う UPDATE ステートメントをサポートしている場合は特に、SQL の 2 番目の (一時) テーブルですべてを実行できる可能性があります。しかし、配列を使用してシングルトンの更新を実行するのは、おそらく同じくらい簡単です。この更新の進行中は、乱数列に一意の制約は必要ないでしょう。

于 2012-12-15T20:40:25.813 に答える