Tablodan, ama oran ile rastgele satır seçmek?

3 Cevap php

Ben (yani şemsiye, çizme, el çantası, ne olursa olsun) sisteminde çeşitli nesnelere açıklayan bir tablo var. Bu nesnelerin her biri ayrı bir yaygınlık ve sıklığını olması gerekir. Örneğin, şemsiye botlar daha nadirdir. Bu faktörlere dayanarak, ben rastgele insidans değere dayalı (boş veya 'bulunamadı nesnesinin' dahil) tek bir nesneyi seçmek gerekir.

Eyvah. Mantıklı?

3 Cevap

Ben, bunun için symcbean için 1 symcbean cevabını değiştirmek için gidiyorum.

SELECT * FROM some_table
WHERE (100*RAND()) < some_table.percent_probability

Bu sezgisel onlara atamak istediğiniz olasılık maç TÜM sonuçları dönecektir. Örneğin, 20 bir olasılık ile 5 nesnelerin her zaman% 20 döndürülür. 90 bir değere sahip nesneler zaman% 90 döndürülür.

Yani sonuç birden fazla nesne olacak, ancak sık sık gösterilmesini nadir olanları muhafaza ettik. Yani şimdi sadece rastgele sonuçlarınızın birini kapmak. Kolay bir yolu, dizideki hepsini sopa olacağını ve:

$items = array(); // assuming you've already filled $items with your 
                  // query results, one item for each array key

$count = count($items);

$chosen_key = rand(1,$count)-1;

$chosen_item = $items[$chosen_key];
SELECT * FROM some_table
WHERE (100*RAND()) > some_table.percent_probability
LIMIT 1

.... Ve seçme olasılığı percent_probability alanında depolanır.

C.

Eğer bir yazma-nadiren-salt birçok senaryo varsa, tek bir rastgele bir değer varsa açıkça almaya itiraz hangi karar böylece olasılık değerleri önceden hesaplamak isteyebilirsiniz (yani nadiren nesneleri ve olasılıkları değiştirme) (tek bir seçim ile, sıralama yok, tüm kayıtların bir karşılaştırma gereklidir).

E.g. (probabilities in per-mill)
umbrella: 500‰ chance
boots: 250‰ chance
satchel: 100‰ chance
whatever: 100‰ chance
"nothing": 50‰ chance

0 ve 499 aracı "şemsiye" arasında bir rastgele sayı böylece, 500-749 "bot" aldı ve olmuştur.

INSERT INTO foo (name, randmin, randmax) VALUES
  ('umbrella', 0, 499),  
  ('boots', 500, 749),
  ('satchel', 750, 849), 
  ('whatever', 850, 949) 

Eğer bir nesne eklemek veya bu tabloyu yeniden oluşturmak olasılıkları değiştirmek her zaman.

Sonra ihtiyacınız gibi bir sorgu

SELECT
  f.name
FROM
  (  
    SELECT Round(Rand()*1000) as r    
  )  as tmp
JOIN
  foo as f  
ON
  r BETWEEN f.randmin and f.randmax  
LIMIT
  1

Sadece bir rasgele değer elde edilecek olan ve MySQL hızla kaydı bulmak için (randmin, randmax) üzerinde bir dizin kullanabilirsiniz.