Как создать случайное число без повторения в базе данных с помощью PHP?
Я хотел бы создать 5-значное число, которое не повторяется внутри базы данных.
Скажем, у меня есть таблица с именем numbers_mst с полем с именем my_number.
Я хочу сгенерировать номер так, чтобы он не повторялся в этом поле my_number.
И предыдущие нули разрешены в этом. Таким образом, номера, такие как 00001, разрешены.
Другое дело, что это должно быть между 00001 и 99999. Как я могу это сделать?
Одна вещь, которую я могу угадать, - это, возможно, создать рекурсивную функцию для проверки числа в таблице и генерации.
Ответы
Ответ 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