2012-04-05 7 views
0

Lets einfach auf seine einfachste, eine Tabelle mit zwei Feldern setzen: 'item_id' & 'times_seen'.Auswählen einer zufälligen Zeile, die vorher nicht ausgewählt wurde?

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

Ich versuche, einen Weg zu finden, zufällig eine Zeile auszuwählen, aber den Vorzug geben, Gegenstände, die nicht viel vor ausgewählt haben.

(offensichtlich eine zweite Abfrage den ‚mal-gesehen‘ zu erhöhen Feld geschickt werden würde, nachdem er ausgewählt wurde)

Obwohl mein aktuelles „Projekt“ ist ein PHP/MySQL ein, würde ich wie sprachunabhängige Lösungen, wenn möglich. Ich hätte lieber eine mathematisch basierte Lösung, die anderswo angepasst werden könnte. Ich bin jedoch nicht gegen eine PHP-Lösung. Ich möchte nur verstehen, wie der Code funktioniert, anstatt ihn einfach zu kopieren und einzufügen.

+0

Was meinen Sie mit "Präferenz geben?" Wäre es in Ordnung, wenn du nie den gleichen Gegenstand zweimal generiert hättest, bis du alles andere generiert hast? Oder sollte es immer möglich sein, einen Artikel zu generieren? – templatetypedef

+0

sollte es immer möglich sein, irgendeinen Gegenstand zu erzeugen –

Antwort

2

Wie über eine SQL-Lösung mit einer einzigen Zeile auswählt:

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

Wie viel Sie multiplizieren random mit (Es ist ein Wert zwischen 0 und 1) hängt davon ab, wie viel Zufälligkeit Sie wollen ..

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

+1

+1 Dachte über etwas ähnliches, aber schaffte es nicht bis zum Ende. Das ist einfach und genial! :-) – Basti

+0

Ich verstehe, dass zu jedem Feld eine andere Zufallszahl hinzugefügt wird, damit dies funktioniert, aber tut MySQL das auch, oder fügt es allen Feldern die gleiche Zufallszahl hinzu. –

+1

Andere Zufallszahl .. Sonst würde es nicht funktionieren .. Und es tut. – barsju

2
  1. Fetch alle Zeilen in der Tabelle
  2. den maximalen Wert fest, für times_seen
  3. jeder Reihe ein Gewicht von max - times_seen
  4. Pick-aus Liste Vergeben Gewichte basierend auf

Schritt 4 ist das knifflige Teil, aber Sie könnten alles so machen:

$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); 

Um alles in SQL zu tun:

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

Diese mit Gewichtungen umgekehrt proportional zur times_seen

Verwandte Themen