web-gelistirme-sc.com

PHP kullanarak veritabanında tekrar olmadan rastgele sayı üretmek nasıl?

Veritabanının içinde tekrarlanmayan 5 basamaklı bir sayı oluşturmak istiyorum .. Diyelim ki, my_number alanlı numbers_mst adında bir tablom var.

Sayıyı bu my_number alanında tekrarlanmadığı şekilde üretmek istiyorum. Ve bundan önceki sıfırlara izin verilir. Yani 00001 gibi rakamlara izin verilir. Başka bir şey 00001 ila 99999 arasında olmalıdır. Bunu nasıl yapabilirim?

Burada tahmin edebileceğim bir şey, tablodaki sayıyı kontrol etmek ve oluşturmak için özyinelemeli bir işlev oluşturmak zorunda kalabilirim.

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

Bu ne yapar:

  1. Rand () kullanarak 0 - 1 arasında rasgele sayı seçer.
  2. 0 - 99999 arasında bir sayı olması için yükseltir.
  3. Sadece zaten tabloda bulunmayanları seçer.
  4. Sadece 1 sonuç döndürür.
50
Tushar

Numbers_mst boş olduğunda çalışmasını sağlamak için Tushar'ın cevabına ek olarak:

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
11
Stijn Van Bael

NOT: Gönderilen diğer çözümler işe yarar - sadece eğer sütun NOT NULL olarak yapılandırılmışsa. NULL ise, sadece sonuç döndürmez. Sorguyu bu şekilde düzeltebilirsiniz:

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 NULLgerekli!

EDIT: Sadece iç SELECT 'ın tablo ismini kasıtlı olarak kaldırdığımı, sadece gerekli seme olmadığından ve tabloda veri yoksa, kırıldığını düşündüğümden bahsetmek istedim. Ancak, belki de bu kasıtlı olarak dahil edildi? - Lütfen herkes için netleştirin veya yorum yapın, teşekkürler.

4
Ben Guild

Bu veritabanı kontrol olmadan benzersiz kod üreteci oluşturmak için en kolay yöntemdir, veritabanı sorgu yürütme zamanından tasarruf sağlar.

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

Keyfini çıkarın, güzel bir kodlama günü ..

:)

3
Roni
  1. Rastgele sayı üret.

  2. Rasgele sayının veritabanında olup olmadığını kontrol edin.

  3. Değilse, dur, bu numarayı kullan.

  4. 1. adıma gidin.

2
David Schwartz

İki yaklaşımın var:

Birincisi, başka bir cevapta önerilen, rastgele bir sayı oluşturmak (mt_Rand () kullanarak) ve veritabanında olmadığını kontrol etmektir. Veritabanındaysa, yeniden düzenleyin ve tekrar deneyin. Tek bir numara oluşturuyorsanız, bu basittir - kod için diğer cevaplara bakınız. Fakat sayıların% 50'sinden fazlasını şereflendiriyorsanız, çok yavaş ve verimsiz olacaktır.

Çok sayıda numara istiyorsanız, alternatif bir veritabanını tüm kayıtlarla doldurmak ve bir sütunu "toplanmış" yapmaktır. Kaç tane "seçilmediğini" bulmak için bir sorgu çalıştırın ve ardından 0 ile "seçilmemiş" sayısı arasında rasgele bir sayı bulun. Ardından, sayıyı bu pozisyonda almak için SQL sorgusunu çalıştırın (seçilmediyse, mysql'de LIMIT kullanın) ve seçili olarak işaretleyin. Biraz sarsılmış, sadece birkaç sayı istiyorsanız, daha fazla iş ve daha az verimli, ancak sayıların% 50'sinden daha fazlasını elde etmek istediğinizde daha iyi olacaktır.

Not: Yerel olarak seçilen sayımı yerel olarak saklayarak ve birkaç daha az sorgu çalıştırarak daha verimli hale getirebilirsiniz.

2
Robbie

Aşağıdaki sorgu, 0'dan 99,999'a kadar tüm int'yi üretir, hedef tabloda kullanılmayan değerleri bulur ve bu boş sayılardan birini rastgele çıkarır: 

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

Tamam, uzun, yavaş ve ölçeklenebilir değil ama bağımsız bir sorgu olarak çalışıyor! Aralığı artırmak veya azaltmak için daha fazla "0" (Katılma a, b, c, d, e) ekleyebilirsiniz.

Bu tür satır üretme tekniğini, örneğin tüm tarihlere sahip satırlar oluşturmak için de kullanabilirsiniz.

0
Jerem
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 ;

Bu saklı yordamı kullanın ve bunu gibi dinamik değerlerle kullanabilirsiniz. 

call GenerateUniqueValue('tablename', 'columnName')

Bununla basitçe bunu yapabiliriz:

$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 veritabanında bulunmayan değere sahip olacaktır.

0
Arju S Moon

Çok basit, bu saklı yordamda MySQL kodunu yaptım

Rasgele 8 basamaktan oluşan sayıyı ve ayrıca benzersiz olarak veritabanındaki tabloyu oluşturur.

Benim için çalışıyor.

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
0
MD_AAQIL

Cevabımın geciktiğini biliyorum, ancak ileride bu konuyu aramaya devam eden, başında sıfır olan rasgele bir sayıya sahip olmayan biri varsa LPAD() işlevini eklemelisiniz.

Yani sorgunuz beğenecek

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

İyi günler dilerim.

0
Jafar Pager Jaya