Подтвердить что ты не робот

Как создать случайное число без повторения в базе данных с помощью PHP?

Я хотел бы создать 5-значное число, которое не повторяется внутри базы данных. Скажем, у меня есть таблица с именем numbers_mst с полем с именем my_number.

Я хочу сгенерировать номер так, чтобы он не повторялся в этом поле my_number. И предыдущие нули разрешены в этом. Таким образом, номера, такие как 00001, разрешены. Другое дело, что это должно быть между 00001 и 99999. Как я могу это сделать?

Одна вещь, которую я могу угадать, - это, возможно, создать рекурсивную функцию для проверки числа в таблице и генерации.

4b9b3361

Ответ 1

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

Что это делает:

  • Выбор случайного числа между 0 - 1 с помощью RAND().
  • Усиляет это число от 0 до 99999.
  • Выбирает только те, которые еще не существуют в таблице.
  • Возвращает только 1 результат.

Ответ 2

В дополнение к ответу Тушара, чтобы заставить его работать, когда number_mst пуст:

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

Ответ 3

ПРИМЕЧАНИЕ. Другие опубликованные решения будут работать только, если столбец настроен как NOT NULL. Если NULL, он просто не вернет никаких результатов. Вы можете исправить запрос следующим образом:

SELECT random_num
FROM (
  SELECT FLOOR(RAND() * 99999) AS random_num
) AS numbers_mst_plus_1
WHERE random_num NOT IN (SELECT my_number FROM numbers_mst WHERE my_number IS NOT NULL)
LIMIT 1

... Требуется ...WHERE my_number IS NOT NULL!

РЕДАКТИРОВАТЬ: Я просто хотел упомянуть, что я намеренно удалил внутреннее имя таблицы SELECT, потому что он не был необходим и, казалось, сломался, если в таблице еще не было данных. Однако, возможно, это было намеренно включено? - Пожалуйста, уточните или прокомментируйте все, спасибо.

Ответ 4

  • Генерация случайного числа.

  • Проверьте, нет ли случайного числа в базе данных.

  • Если нет, остановитесь, используйте этот номер.

  • Перейдите к шагу 1.

Ответ 5

Это самый простой способ создания уникального генератора кода без проверки базы данных, он сохранит время выполнения запроса базы данных.

function unique_code_generator($prefix='',$post_fix='')
    {
        $t=time();
        return ( rand(000,111).$prefix.$t.$post_fix);
    }

Наслаждайтесь, получите хороший день кодирования.

:)

Ответ 6

У вас есть два подхода:

Первым, предложенным в другом ответе, является создание случайного числа (с использованием mt_rand()) и проверка его не в базе данных. Если он находится в базе данных, повторите попытку и повторите попытку. Это проще всего, если вы генерируете один номер - см. Другие ответы на код. Но если вы получаете более 50% от числа, это будет очень медленно и неэффективно.

Если вам нужно много номеров, альтернативой является заполнение базы данных всеми записями и наличие столбца "выбрано". Запустите запрос, чтобы узнать, сколько "не выбрано", а затем найдите случайное число между 0 и числом "не выбрано". Затем запустите SQL-запрос, чтобы получить номер в этой позиции (где не выбрано, используйте LIMIT в mysql) и отметьте как выбрано. Немного запутанный, он больше работает и менее эффективен, если вы хотите только несколько чисел, но будет намного лучше, если вы захотите получить более 50% (оценки) чисел.

Примечание. Вы можете сделать его более эффективным, сохранив подсчет, выбранный локально, и запустив несколько менее запросов.

Ответ 7

Я знаю, что мой ответ задерживается, но если кто-то ищет этот предмет в будущем, у кого не будет случайного числа с начальным нулем, вы должны добавить функцию LPAD().

Итак, ваш запрос понравится

SELECT LPAD(FLOOR(RAND()*99999),5,0)

Хороший день.

Ответ 8

Следующий запрос генерирует все int от 0 до 99,999, находит значения, которые не используются в целевой таблице, и произвольно выводит одно из этих свободных чисел:

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), чтобы увеличить или уменьшить диапазон.

Вы также можете использовать такой метод генерации строк для создания строк со всеми датами, например.

Ответ 9

DELIMITER $$

USE 'temp' $$

DROP PROCEDURE IF EXISTS 'GenerateUniqueValue'$$

CREATE PROCEDURE 'GenerateUniqueValue'(IN tableName VARCHAR(255),IN columnName VARCHAR(255)) 
BEGIN
    DECLARE uniqueValue VARCHAR(8) DEFAULT "";
    DECLARE newUniqueValue VARCHAR(8) DEFAULT "";
    WHILE LENGTH(uniqueValue) = 0 DO
        SELECT CONCAT(SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1),
                SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789', RAND()*34+1, 1)
                ) INTO @newUniqueValue;
        SET @rcount = -1;
        SET @query=CONCAT('SELECT COUNT(*) INTO @rcount FROM  ',tableName,' WHERE ',columnName,'  like ''',newUniqueValue,'''');
        PREPARE stmt FROM  @query;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
    IF @rcount = 0 THEN
            SET uniqueValue = @newUniqueValue ;
        END IF ;
    END WHILE ;
    SELECT uniqueValue;
    END$$

DELIMITER ;

Используйте эту хранимую процедуру, и вы можете использовать ее с динамическими значениями, такими как

call GenerateUniqueValue('tablename', 'columnName')

Ответ 10

Мы можем просто сделать это:

$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 будет иметь значение, которого нет в базе данных

Ответ 11

Очень просто, я сделал код в MySQL в этой хранимой процедуре

Он генерирует случайное число из 8 цифр, а также уникально с таблицей в базе данных.

Это работает для меня.

CREATE DEFINER='pro'@'%' PROCEDURE 'get_rand'()
BEGIN
DECLARE regenerateNumber BOOLEAN default true;
declare regNum int;
declare cn varchar(255);
repeat
SET regNum      := FLOOR(RAND()*90000000+10000000);
SET cn =(SELECT count(*) FROM stock WHERE id = regNum);
select regNum;
if cn=0
then
SET regenerateNumber = false;
end if;
UNTIL regenerateNumber=false
end repeat;
END