How to Generate Random number without repeat in database using PHP?

后端 未结 11 2003
清酒与你
清酒与你 2020-12-02 11:15

I would like to generate a 5 digit number which do not repeat inside the database. Say I have a table named numbers_mst with field named my_number

相关标签:
11条回答
  • 2020-12-02 12:06
    1. Generate random number.

    2. Check if random number is in database.

    3. If not, stop, use this number.

    4. Go to step 1.

    0 讨论(0)
  • 2020-12-02 12:08
    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 ;
    

    Use this stored procedure and you can use this with dynamic values like

    call GenerateUniqueValue('tablename', 'columnName')
    
    0 讨论(0)
  • 2020-12-02 12:09

    The folowing query generates all int from 0 to 99,999, find values which are not used in the target table and output one of these free number randomly :

    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
    

    Ok, it is long, slow and not scalable but it works as a standalone query! You can add a remove more "0" (Joins a, b, c, d, e) to increase or reduce the range.

    You can also use this kind of rows generator technique to create rows with all dates for example.

    0 讨论(0)
  • 2020-12-02 12:11
    SELECT FLOOR(RAND() * 99999) AS random_num
    FROM numbers_mst 
    WHERE "random_num" NOT IN (SELECT my_number FROM numbers_mst)
    LIMIT 1
    

    What this does:

    1. Selects random number between 0 - 1 using RAND().
    2. Amplifies that to be a number between 0 - 99999.
    3. Only chooses those that do not already exist in table.
    4. Returns only 1 result.
    0 讨论(0)
  • 2020-12-02 12:11

    In addition to Tushar's answer to make it work when numbers_mst is empty:

    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
    
    0 讨论(0)
提交回复
热议问题