如何使用PHP在数据库中重复生成随机数而不重复?

时间:2012-07-27 00:41:32

标签: mysql

我想生成一个5位数字,不会在数据库中重复。 假设我有一个名为 numbers_mst 的表格,其中包含名为 my_number 的字段。

我想在此my_number字段中生成不重复的数字。 此前允许前面的零。所以允许像00001这样的数字。 另一件事是它应该在00001到99999之间。我怎么能这样做?

我可以猜到的一件事是我可能需要创建一个递归函数来检查数字到表并生成。

10 个答案:

答案 0 :(得分:52)

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个结果。

答案 1 :(得分:12)

除了Tushar的回答,当numbers_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

答案 2 :(得分:4)

注意:如果列已配置为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的表名,因为它没有必要,如果没有数据,它似乎就会中断桌子呢?但是,这可能是有意包含的吗? - 请为每个人澄清或评论,谢谢。

答案 3 :(得分:2)

  1. 生成随机数。

  2. 检查数据库中是否有随机数。

  3. 如果没有,请停止使用此号码。

  4. 转到第1步。

答案 4 :(得分:2)

您有两种方法:

在其他答案中建议的第一个是创建一个随机数(使用mt_rand())并检查它不在数据库中。如果它在数据库中,请重新注册并重试。如果您生成一个数字,这是最简单的 - 请参阅代码的其他答案。但是,如果你更多地掏出那50%的数字,那将是非常缓慢和低效的。

如果你需要大量的数字,另一种方法是使用所有记录填充数据库并选择一个列。运行查询以查找“未挑选”的数量,然后找到0和“未挑选”数字之间的随机数。然后运行SQL查询以获取该位置的数字(未选中的位置,在mysql中使用LIMIT)并标记为已选中。有点复杂,如果你只想要一些数字,那就更有效,效率更低,但如果你想获得50%(估计数字)的数字,那就更好了。

注意:您可以通过存储本地选择的计数并运行少量查询来提高效率。

答案 5 :(得分:0)

我知道我的答案很晚,但是如果有人在将来寻找这个主题,谁不会有一个前导零的随机数,你应该添加LPAD()函数。

所以你的查询会是

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

度过愉快的一天。

答案 6 :(得分:0)

下面的查询生成从0到99,999的所有int,找到目标表中未使用的值,并随机输出其中一个免费数字:

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)增加或减少范围。

您也可以使用这种行生成器技术创建包含所有日期的行。例如。

答案 7 :(得分:0)

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')

答案 8 :(得分:0)

我们可以简单地做到这一点:

(\/owner\/reservation-confirmation\?bv=true&type=Future&reservationNo=.*)|(\/owner\/reservation-confirmation\?type=Future&reservationNo=.*)|(\/owner\/reservation-confirmation\?bv=true&reservationNo=.*)

$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); 将具有数据库中不存在的值

答案 9 :(得分:0)

很简单,我在该存储过程中的MySQL中进行了代码

它生成8位随机数,并且与数据库中的表唯一。

对我有用。

await doc.xlsx.write(stream)
  .then(() =>{
    return   s3.upload({
    Key: file_key,
        Bucket: S3Service.bucket,
    Body: stream,
    ContentType: 'CONTENT_TYPE_EXCEL'
        }).promise();
    })
    .catch((error) => {
    console.log(error);
    return undefined;
});