Tirage au sort aléatoire pondéré dans une requête SQL [Résolu]

Evangun 1982 Messages postés dimanche 20 février 2005Date d'inscription 24 septembre 2012 Dernière intervention - 24 juil. 2008 à 13:41 - Dernière réponse : Evangun 1982 Messages postés dimanche 20 février 2005Date d'inscription 24 septembre 2012 Dernière intervention
- 26 juil. 2008 à 02:33
Bonjour à tous,

je vous soumets une petite colle ! du genre qui fait cogiter, sauf si vous êtes superman.

Il s'agit de trouver une requête SQL qui ferait un tirage au sort pondéré. Je ne demande pas de script php qui fasse ça, je connais déjà bien. Ce que je veux c'est vraiment que SQL me renvoie le résultat.

Dans ma table j'ai des lignes, et chaque ligne contient dans un champ son coefficient de pondération, c'est-à-dire le pourcentage de chance qu'elle a d'être tirée.

Par exemple

# de ligne         #coefficient
Ligne 1 :          34
Ligne 2 :          33
Ligne 3 :          33

Jusqu'à présent je n'ai rien trouvé. Je me dis que la seule solution c'est de rajouter deux champs, qui me permettront d'utiliser un nombre aléatoire avec RAND tiré entre 1 et 100.
Exemple des lignes :

# de ligne         #coefficient     #debutdeplage         #findeplage
Ligne 1 :          34                   1                             34

Ligne 2 :          33                   35                           57

Ligne 3 :          33                   58                           100

Si vous avez une idée n'hésitez pas !
Merci
Afficher la suite 

6 réponses

Répondre au sujet
coucou747 12336 Messages postés mardi 10 février 2004Date d'inscription 30 juillet 2012 Dernière intervention - 24 juil. 2008 à 19:07
+3
Utile
salut

on va prendre un truc un peu moins aleatoire :

# de ligne #coefficient
Ligne 1 : 20
Ligne 2 : 20
Ligne 3 : 60

mysql> CREATE DATABASE test
-> ;
Query OK, 1 row affected (0.11 sec)

mysql> USE test
Database changedmysql> CREATE TABLE foo (id int unsigned auto_increment, ligne char(5), pourcent int, primary key(id));
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO foo(ligne, pourcent) VALUES ("l1", 20), ("l2", 20), ("l3", 60);
Query OK, 3 rows affected (0.04 sec)
Records: 3 Duplicates: 0 Warnings: 0

mysql> SELECT * FROM foo;
+----+-------+----------+
| id | ligne | pourcent |
+----+-------+----------+
| 1 | l1 | 20 |
| 2 | l2 | 20 |
| 3 | l3 | 60 |
+----+-------+----------+
3 rows in set (0.00 sec)

mysql> SELECT ligne, (SELECT SUM(pourcent) FROM foo AS b WHERE b.id <= a.id) FROM foo AS a;
+-------+---------------------------------------------------------+
| ligne | (SELECT SUM(pourcent) FROM foo AS b WHERE b.id <= a.id) |
+-------+---------------------------------------------------------+
| l1 | 20 |
| l2 | 40 |
| l3 | 100 |
+-------+---------------------------------------------------------+
3 rows in set (0.00 sec)

ensuite, en bidouillant un peu, on arrive a faire ca :

mysql> SET @random = ROUND(RAND() * 100);
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @random AS rand, (SELECT ligne FROM (SELECT id, ligne, (SELECT SUM(pourcent) FROM foo AS b WHERE b.id <= a.id) AS percent FROM foo AS a) AS sub WHERE percent > rand ORDER BY id ASC LIMIT 1) AS ligne;
+------+-------+
| rand | ligne |
+------+-------+
| 99 | l3 |
+------+-------+
1 row in set (0.00 sec)


chaque fois que j'ai tente de combiner les deux, mysql fout sa merde...
Cette réponse vous a-t-elle aidé ?  
Commenter la réponse de coucou747
Evangun 1982 Messages postés dimanche 20 février 2005Date d'inscription 24 septembre 2012 Dernière intervention - 24 juil. 2008 à 13:43
0
Utile
Je me rends compte que mon exemple est idiot puisque les 3 ont la même chance d'être tiré ou presque : 1/3, mais vous avez compris ce que je voulais dire
Commenter la réponse de Evangun
Evangun 1982 Messages postés dimanche 20 février 2005Date d'inscription 24 septembre 2012 Dernière intervention - 24 juil. 2008 à 21:02
0
Utile
Hello et merci de t'être penché sur le problème !
C'est bizarre, mysql me met une erreur lorsque je veux faire ta deuxième requête select. Je suis en train de mettre la mise à jour de mysql, peut-être qu'il faut la dernière version pour pouvoir la faire.
En tout cas c'est très intéressant ton idée et je travaillerai sur cette base demain, là je dois partir. Je vous tiendrai au courant.
Merci encore et bonne soirée
Commenter la réponse de Evangun
coucou747 12336 Messages postés mardi 10 février 2004Date d'inscription 30 juillet 2012 Dernière intervention - 24 juil. 2008 à 21:04
0
Utile
mysql> SELECT VERSION();
+--------------------+
| VERSION() |
+--------------------+
| 5.0.51a-3ubuntu5.1 |
+--------------------+
1 row in set (0.00 sec)
Commenter la réponse de coucou747
Evangun 1982 Messages postés dimanche 20 février 2005Date d'inscription 24 septembre 2012 Dernière intervention - 25 juil. 2008 à 12:44
0
Utile
Hello,

effectivement avec la 5.0.51 ça marche mieux qu'avec la 5.0.27 ! Reste à savoir si je peux disposer de cette version sur mon hébergement qui est mutualisé pour l'instant.
Bon alors félicitations, ça marche nickel !

Pour l'histoire de combiner les deux, oui j'imagine que le problème c'est que mettre un alias au RAND ne suffit pas pour en faire une constante et qu'elle est donc recalculée à chaque sous-requête.

Merci beaucoup pour le coup de main, je n'y aurais pas pensé !
à+
Commenter la réponse de Evangun
Evangun 1982 Messages postés dimanche 20 février 2005Date d'inscription 24 septembre 2012 Dernière intervention - 26 juil. 2008 à 02:33
0
Utile
Pour info à ceux qui tomberont sur ce message, on ne peut vraiment pas faire confiance à RAND de MySQL pour trouver un nombre aléatoire. Les résultats sont complètement faussés par rapport aux pondérations. Avec un random fourni par php par contre, tout marche bien.
Commenter la réponse de Evangun

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.