2012-04-05 69 views
0

讓我們把它放在最簡單的表格中,它有兩個字段:'item_id'&'times_seen'。選擇之前未被選擇的隨機行嗎?

| item_id | times_seen | 
----------+------------- 
| 1001 |  48  | 
| 1002 |  25  | 
| 1003 |  1  | 
| 1004 |  12  | 
| 1005 |  96  | 
| 1006 |  35  | 

我試圖找到一種方法來隨機選擇一個行,但優先選擇以前沒有被選擇過的項目。

(顯然,第二個查詢將被髮送到遞增「次見過」字段已經被選中後)

雖然我目前的「項目」是一個PHP/MySQL的一個,我會如果可能,就像語言不可知的解決方案我寧願有一個基於數學的解決方案,可以在其他地方進行調整。我並不反對php解決方案。我只想能夠理解代碼如何工作,而不是複製和粘貼它。

+0

你是什麼意思「優先選擇?」如果你從來沒有生成過同樣的東西兩次,直到你生成了其他東西,它會沒事嗎?或者應該始終可以生成一個項目? – templatetypedef 2012-04-05 22:31:56

+0

它應該始終可以生成任何項目 – 2012-04-05 22:36:52

回答

2

怎麼樣SQL解決方案:

select * from item order by times_seen + Rand()*100 limit 1; 

你多少錢乘隨機與(其值介於0和1之間)取決於你想要多少隨機性。

編輯:http://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_rand

+1

+1思考類似的東西,但不會讓它結束。這簡直太棒了! :-) – Basti 2012-04-05 22:48:55

+0

據我所知,每個字段都會添加一個不同的隨機數字,但是mysql確實會這樣做,還是會將相同的隨機數字添加到所有字段中。 – 2012-04-05 23:00:21

+1

不同的隨機數..否則它不會工作..它確實如此。 – barsju 2012-04-05 23:02:04

2
  1. 提取所有表中的行
  2. 確定爲times_seen
  3. 最大值指定每一行從列表max - times_seen
  4. 皮克的基於體重

步驟4是一個重棘手的部分,但你可以這樣做:

$max = 1; 
$rows = array(); 

$result = mysql_query("SELECT * FROM table"); 
while ($row = mysql_fetch_array($result)){ 
    $max = max($max, $row['times_seen']); 
    $rows[] = $row; 
} 

$pick_list = array(); 
foreach ($rows as $row){ 
    $count = $max - $row['times_seen']; 
    for ($i=0; $i<$count; $i++) $pick_list[] = $row['item_id']; 
} 
shuffle($pick_list); 
$item_id = array_pop($item_id); 

要做到這一切在SQL:

SELECT * 
FROM table 
ORDER BY RAND() * (MAX(times_seen) - times_seen) DESC 
LIMIT 1 

這將選擇一個單行的權重成反比times_seen