i'm trying to write a query that will select a number of articles from a table randomly, but the articles have weighted chances to be chosen. i've come up with a solution, but it seems clumsy to me, and i was wondering if anyone has any ideas on how to do it better. i need at least 1 article, but it would be helpful if the query returned several at once.
here is my approach :
the table --
mysql> describe randomiser;
+---------+----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+----------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| article | varchar(30) | YES | | NULL | |
| chance | smallint(5) unsigned | NO | MUL | 1 | |
| low | int(10) unsigned | NO | MUL | 0 | |
| high | int(10) unsigned | NO | | 0 | |
+---------+----------------------+------+-----+---------+----------------+
my test population --
mysql> select * from randomiser;
+----+-------------+--------+-----+------+
| id | article | chance | low | high |
+----+-------------+--------+-----+------+
| 1 | common | 128 | 1 | 128 |
| 2 | uncommon | 64 | 129 | 192 |
| 3 | infrequent1 | 32 | 193 | 224 |
| 4 | infrequent2 | 32 | 225 | 256 |
| 5 | infrequent3 | 32 | 257 | 288 |
+----+-------------+--------+-----+------+
the low and high values are updated on insert, any time someone adds a new article to the table.
my selection method --
SET @t:=(SELECT FLOOR( SUM(chance) * RAND() + 1) FROM randomiser);
SELECT article FROM randomiser WHERE @t >= low AND @t <= high;
- is it possible to combine the selects into a single, efficient statement ?
- is it possible to write a select that will pull several random values instead of only one ?
NOTE - i am not at all attached to the table as i've defined it ; if there's a different sort of layout so it will be more efficient, i would like to know !
Aucun commentaire:
Enregistrer un commentaire