Requete sql: RAND + LIMIT

Eléphant du PHP | 66 Messages

17 oct. 2006, 19:19

Bonsoir,

voila je buche sur un probleme. Dans une de mes pages j'affiche les 40 derniers enregistrements d'une table qui contient des centaines d'entrées. Mon but est de les afficher aléatoirement mais voila la fonction RAND passe avant le LIMIT.

plus concrètement voici ma requete
$sql="SELECT * FROM matable ORDER BY RAND() LIMIT 0,40";
Cette requete va donc chercher 40 résultats au hasard dans ma table et les affiche. Moi ce que je veut c'est qu'il m'affiche les 40 derniers enregistrements de la table mais aléatoirement.

Savez vous comment je peux faire ???

j'avais pensé de d'abord récupérer les id des 40 entrées en question dans un tableau et ensuite d'aller les rechercher 1 par 1 dans la base mais je n'ai pas trouvé de fonction permettant de trier un tableau aléatoirement.

Auriez vous des idées sur un moyen simple de réaliser ca ?

je vous remercie d'avance:)

ViPHP
ViPHP | 1961 Messages

17 oct. 2006, 20:01

Bonsoir,

La fonction PHP array_rand() devrait te convenir, pour plus de détails regarde ICI
Deux choses sont infinies, l'Univers et la sottise humaine!!
Mais je ne suis pas sur de ce que j'affirme au sujet de l'Univers.

A. Einstein

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

17 oct. 2006, 21:19

Tu peux le faire en SQL grâce à une table dérivée si ta version de MySQL le permet:

Code : Tout sélectionner

SELECT * FROM ( SELECT * FROM table ORDER BY id DESC LIMIT 40 ) AS tmp ORDER BY RAND()
Sinon, tu peux le faire en PHP comme le suggère Ajoloca, à la différence près que je recommanderais plutôt shuffle() suivi d'un simple foreach

Eléphant du PHP | 66 Messages

18 oct. 2006, 13:48

Je vous remercie pour vos réponses. Entre temps j'ai fais des tests et j'ai procédé a une autre solution. En fait j'ai fait un script dans mon admin qui réorganise les id, donc qui réattribue les id a partir de 1. Ainsi, je peux avec "WHERE" filtrer les résultats a ma guise.

Parcontre un autre probleme survient maintenant, l'auto increment ne joue pas le jeu et chaque nouveaux enregistrements ne suit pas les derniers id. ce qui m'obligerai a relancer mon script a chaque nouvelles entrées, c'est un peu de la requete dans le vent.

Je voudrai savoir si il y'a moyen de remettre l'auto increment au meme niveau que les enregistrements de la table. J'ai fais des recherche et il y'a le flush qui recharge la table et supprime les divers cache mais est-ce que ca réglerai mon probleme ?

Encore merci ;)

edit: Bon, apres reflexion, c'est pas très rassurant comme procédé, c'est meme plutot risqué, je vais donc me penché sur le systeme par tableau. Dsl pour le post inutile. Je teste ca et je met resolu si tout ce passe bien.


Merci.
Modifié en dernier par Vince le 18 oct. 2006, 14:22, modifié 1 fois.

Modérateur PHPfrance
Modérateur PHPfrance | 6037 Messages

18 oct. 2006, 14:18

Parcontre un autre probleme survient maintenant, l'auto increment ne joue pas le jeu et chaque nouveaux enregistrements ne suit pas les derniers id.
Quelle version de MySQL ?
Règle n°2 du webmaster : Toujours commencer par le HTML qu'on veut obtenir....toujours ! :priere:
J'aime apprendre de nouvelles choses.

Eléphant du PHP | 66 Messages

18 oct. 2006, 14:23

MySQL - 4.1.11 phpMyAdmin - 2.8.0.3

mais j'ai édité mon post plus haut et a moins que vous me disiez qu'il y'a une solution adaptée à cela sans trop trifouiller la table, je vais me pencher sur une autre solution.

ViPHP
ViPHP | 1961 Messages

18 oct. 2006, 14:31

Bonjour,

J'ai bien une solution qui est un peu longue mais qui fonctionne (à condition que tes tables n'utilisent pas InnoDB et tes colonnes soient référencées)

étape 1:
Créer une table avec la même structure et les données triées par id

Code : Tout sélectionner

CREATE TABLE temp_tbl SELECT * FROM ta_table ORDER BY id;
étape 2:
deux solutions:
étape 2.a Supprimer les enregistrements de la table 'mère'

Code : Tout sélectionner

TRUNCATE TABLE ta_table;
étape 2.b Supprimer la table 'mère'

Code : Tout sélectionner

DROP TABLE ta_table;
Si tu as choisis la 2.a

Code : Tout sélectionner

INSERT INTO ta_table VALUES SELECT * FROM temp_table;
et suppression de la table temp

Code : Tout sélectionner

DROP TABLE temp_tbl;
Si tu as choisi 2.b
Renommer la table temp

Code : Tout sélectionner

RENAME TABLE temp_tbl TO ta_table;
Deux choses sont infinies, l'Univers et la sottise humaine!!
Mais je ne suis pas sur de ce que j'affirme au sujet de l'Univers.

A. Einstein

Modérateur PHPfrance
Modérateur PHPfrance | 6037 Messages

18 oct. 2006, 14:36

Note :c'est plus optimisé de faire faire le boulot à MySQL plutôt qu'à PHP.
Règle n°2 du webmaster : Toujours commencer par le HTML qu'on veut obtenir....toujours ! :priere:
J'aime apprendre de nouvelles choses.

Eléphant du PHP | 66 Messages

18 oct. 2006, 15:51

Ca y'est, j'ai tester et j'ai opter pour la solution d'ajoloca.

j'ai juste du l'adapter pour que mon champ id aie la clé index sur la table dupliquée mais tout fonctionne correctement.

Un grand merci.

Résolu donc.