Bonsoir,
Attention au fait que order by rand() devient rapidement très lent si la table est volumineuse.
Au-delà de quelques milliers d'enregistrements déjà, ce n'est plus trop recommandé.
Dans ce cas, le plus simple sera sans doute de le faire en trois temps:
1. select count(*) from words
2. Utiliser un langage serveur pour générer 50 nombres pseudo-aléatoires entre 1 et count(*) (PHP, python, Java, etc.)
3. select name from words where id in(...)
Inconvénient: on suppose que les id sont continus, i.e. qu'il n'y a pas de trous. Si on doit prendre en compte les trous, soit la requête va se complexifier notablement, soit il faut faire de la réattribution d'id à la suppression (ce qui peut rapidement être source d'autres problèmes, dont la consistance des références dans le temps)
Avantage: c'est très simple et très rapide
Deuxième solution possible:
Etape de préparation à faire une seule fois:
1. Ajouter une nouvelle colonne, p.ex. randomValue, de type double: alter table words add randomValue double
2. update words set randomValue = rand()
ET pour sélectionner 50 éléments ensuite, on peut procéder par exemple avec:
1. set @random := rand()
2. select name from words order by abs(randomValue-@random) asc limit 50
Gare à ne pas faire order by randomValue-rand() sinon on retombe dans le problème de lenteur
Inconvénient: selon la valeur attribuée à randomValue, toutes les lignes n'ont pas la même probabilité de sortir; les randomValue extrêmums (proches de 0 ou de 1) ont moins de chances, tout comme les randomValue les plus isolés (avec des voisins moins proches) ont plus de chances.
Des systèmes plus ou moins élaborés, réattribuant une nouvelle valeur randomValue aux éléments qui sont sortis, ou une redistribution périodique tous les jours à minuit par exemple, n'ont guère de chance d'augmenter l'équiprobabilité.
A moins que randomValue soit indexée, ça nécéssite un parcours complet de la table, donc ce sera un peu plus lent que de piocher des id
Avantage: tu peux étendre cette solution pour faire un système où tous les éléments doivent avoir été tirés une fois avant de pouvoir être à nouveau tirés une deuxième fois, ce serait alors un aléatoire préparé à l'avance, semblable au bouton shuffle sur les lecteurs de musique. pour cela:
1. On ajoute une colonne compteur: alter words add drawnCount int default 0
2. ET à la sélection: select name from words order by drawnCount asc, randomValue asc limit 50; suivi de update words set drawnCount = drawnCount +1 order by drawCount asc, randomValue asc; pour mettre à jour les lignes qui ont été tirées.
Voilà, j'espère que tu trouveras ton bonheur dans cette réponse. Tirer des lignes au hasard dans une table n'est pas si facile qu'il n'y paraît.