37

データベース内で繰り返されない 5 桁の数字を生成したいと考えています。my_numberという名前のフィールドを持つnumbers_mstという名前のテーブルがあるとします。

この my_number フィールドで繰り返されないように番号を生成したいと考えています。また、これには先行ゼロが許可されます。したがって、00001 のような数字が許可されます。もう 1 つのことは、00001 から 99999 の間である必要があることです。どうすればそれを行うことができますか?

ここで推測できることの 1 つは、数値をテーブルにチェックインして生成する再帰関数を作成する必要があるかもしれないということです。

4

11 に答える 11

57
SELECT FLOOR(RAND() * 99999) AS random_num
FROM numbers_mst 
WHERE "random_num" NOT IN (SELECT my_number FROM numbers_mst)
LIMIT 1

これが何をするか:

  1. RAND() を使用して 0 から 1 の間の乱数を選択します。
  2. それを 0 ~ 99999 の数値に増幅します。
  3. テーブルにまだ存在しないものだけを選択します。
  4. 1 つの結果のみを返します。
于 2012-07-27T00:47:17.077 に答える
12

numbers_mst が空のときに機能させるための Tushar の回答に加えて:

SELECT random_num
FROM (
  SELECT FLOOR(RAND() * 99999) AS random_num 
  UNION
  SELECT FLOOR(RAND() * 99999) AS random_num
) AS numbers_mst_plus_1
WHERE `random_num` NOT IN (SELECT my_number FROM numbers_mst)
LIMIT 1
于 2014-12-03T14:13:15.480 に答える
3
  1. 乱数を生成します。

  2. 乱数がデータベースにあるかどうかを確認します。

  3. そうでない場合は、停止して、この番号を使用してください。

  4. 手順 1 に進みます。

于 2012-07-27T00:46:18.493 に答える
2

次の 2 つの方法があります。

他の回答で提案されている最初の方法は、( mt_rand() を使用して)乱数を作成し、それがデータベースにないことを確認することです。データベースにある場合は、再生成して再試行してください。単一の数値を生成する場合、これが最も簡単です。コードについては、他の回答を参照してください。しかし、数値の 50% 以上を生成している場合は、非常に遅くなり、非効率的になります。

多数の数値が必要な場合は、データベースにすべてのレコードを入力し、列を「選択」することもできます。クエリを実行して「選択されていない」数を見つけ、0 と「選択されていない」数の間の乱数を見つけます。次に、SQL クエリを実行してその位置の番号を取得し (選択されていない場合は、mysql で LIMIT を使用します)、選択済みとしてマークします。少し複雑です。少数の数値のみが必要な場合は、より多くの作業と効率が低下しますが、数値の 50% (推定) を超える数値を取得する場合ははるかに優れています。

注: 選択したカウントをローカルに保存し、実行するクエリをいくつか減らすことで、より効率的にすることができます。

于 2012-07-27T00:53:34.037 に答える
0

これで簡単にできます:

$regenerateNumber = true;

do {
    $regNum      = rand(2200000, 2299999);
    $checkRegNum = "SELECT * FROM teachers WHERE teacherRegNum = '$regNum'";
    $result      = mysqli_query($connection, $checkRegNum);

    if (mysqli_num_rows($result) == 0) {
        $regenerateNumber = false;
    }
} while ($regenerateNumber);

$regNumデータベースに存在しない値を持つ

于 2018-08-27T21:29:22.353 に答える
0

次のクエリは、0 から 99,999 までのすべての int を生成し、ターゲット テーブルで使用されていない値を見つけ、これらの空き番号の 1 つをランダムに出力します。

SELECT random_num FROM (
    select a.a + (10 * b.a) + (100 * c.a) + (1000 * d.a) + (10000 * e.a) as random_num
    from (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as d
    cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as e
) q
WHERE random_num NOT IN(SELECT my_number FROM numbers_mst)
ORDER BY RAND() LIMIT 1

わかりました、長くて遅く、スケーラブルではありませんが、スタンドアロンのクエリとして機能します! さらに「0」を追加して (a、b、c、d、e を結合)、範囲を増減できます。

この種の行ジェネレーター手法を使用して、たとえばすべての日付で行を作成することもできます。

于 2017-11-24T14:08:27.203 に答える