37

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

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

我可以在这里猜到的一件事是我可能必须创建一个递归函数来将数字检查到表中并生成。

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

除了 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
于 2014-12-03T14:13:15.480 回答
7

注意:发布的其他解决方案在列配置为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是必要的!

编辑:我只想提一下,我故意删除了 innerSELECT的表名,因为它似乎没有必要,并且如果表中还没有数据,它似乎会中断?但是,也许这是故意包括在内的?- 请为大家澄清或评论,谢谢。

于 2016-11-11T13:49:01.187 回答
4

这是在不检查数据库的情况下构建唯一代码生成器的最简单方法,它将节省数据库查询执行时间。

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

享受,有一个愉快的编码日..

:)

于 2015-08-15T09:41:55.603 回答
3
  1. 生成随机数。

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

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

  4. 转到步骤 1。

于 2012-07-27T00:46:18.493 回答
2

你有两种方法:

第一个,在其他答案中建议,是创建一个随机数(使用 mt_rand() )并检查它不在数据库中。如果它在数据库中,请重新生成并重试。如果您要生成一个数字,这是最简单的 - 请参阅代码的其他答案。但是,如果您生成的数字超过 50%,它将非常缓慢且效率低下。

如果您想要很多数字,另一种方法是使用所有记录填充数据库并“选择”一列。运行查询以查找“未选择”的数量,然后找到介于 0 和“未选择”的数字之间的随机数。然后运行 ​​SQL 查询以获取该位置的数字(未选择的位置,在 mysql 中使用 LIMIT)并标记为已选择。有点复杂,如果你只想要几个数字,它的工作量更大,效率更低,但是当你想要获得超过 50%(估计)的数字时会好得多。

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

于 2012-07-27T00:53:34.037 回答
2

我知道我的回答迟了,但如果有人在未来寻找这个主题,想要一个前导零的随机数,你应该添加这个LPAD()函数。

所以你的查询会喜欢

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

祝你今天过得愉快。

于 2017-11-13T16:57:23.857 回答
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)来增加或减少范围。

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

于 2017-11-24T14:08:27.203 回答
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')
于 2018-04-12T15:44:50.783 回答
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

很简单,我在那个存储过程中做了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
于 2019-08-17T16:24:54.847 回答