Requete : ORDER BY aléatoire

Eléphanteau du PHP | 29 Messages

09 oct. 2009, 00:26

Bonsoir, je cherche à sélectionner les 5 derniers enregistrement d'une table
Bon ça c'est OK grâce à ce code :
$sql = "SELECT news FROM news ORDER BY id DESC LIMIT 5";
Mais, je veux afficher cette sélection dans un ordre aléatoire lors de l'actualisation de la page...

Toutes les news :
news 1
news 2
news 3
news 4
news 5
news 6
news 7
news 8
...
Ce que j'ai actuellement :
news 4
news 5
news 6
news 7
news 8
Ce que je veut obtenir :
news 8
news 4
news 5
news 7
news 6
J'espère que ces exemples pourront vous aider à m'aider :) Merci
Bienvenue sur :
http://france.webmaster.fr.free.fr
Fabrication en cours...

Mammouth du PHP | 985 Messages

09 oct. 2009, 00:37

Bonsoir,
SQL Server:
ORDER BY NEWID()
MySQL:
ORDER BY RAND()
LIMIT 1
SqlLite:
ORDER BY Random()
LIMIT 1
Le mieux est de regarder plus en détail ici:
http://www.carlj.ca/2007/12/16/selectin ... -with-sql/
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

Eléphanteau du PHP | 29 Messages

09 oct. 2009, 01:20

La requête que je vous est montré était un exemple, voici ma requête (elle fonctionne parfaitement) :
$x_derniere_news = "5";
$sql = "SELECT texte,id FROM news ORDER BY id DESC LIMIT ".$x_derniere_news."";
J'ai essayé :
$x_derniere_news = "5";
$sql = "SELECT texte,id FROM news ORDER BY RAND(id) LIMIT ".$x_derniere_news."";
$x_derniere_news = "5";
$sql = "SELECT texte,id FROM news ORDER BY id RAND() LIMIT ".$x_derniere_news."";
$x_derniere_news = "5";
$sql = "SELECT texte,id FROM news ORDER BY RAND()id LIMIT ".$x_derniere_news."";
$x_derniere_news = "5";
$sql = "SELECT texte,id FROM news ORDER BY RAND(id) LIMIT ".$x_derniere_news."";
Mais ça ne fonctionne pas... Où doit-je mettre le " id " ?

Merci
Modifié en dernier par NewDeveloppeur le 09 oct. 2009, 01:30, modifié 1 fois.
Bienvenue sur :
http://france.webmaster.fr.free.fr
Fabrication en cours...

Mammouth du PHP | 985 Messages

09 oct. 2009, 01:29

Fait comme dans l'exemple:
ORDER BY RAND() LIMIT 1"
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

Eléphanteau du PHP | 29 Messages

09 oct. 2009, 01:35

Oui, merci quand je fait ça :
$sql = "SELECT texte,id FROM news ORDER BY RAND()";
Bah ça fonctionne... Mais comment dire à MYSQL de se référer par rapport à la colonne " id " et de ne prendre que les x derniers?

Quand je fait :
$sql = "SELECT texte,id FROM news ORDER BY RAND() LIMIT 1";
Il prend un enregistrement au hasard mais pas le dernier...

Et quand je fait ça :
$sql = "SELECT texte,id FROM news ORDER BY RAND() LIMIT 100";
Il prend 100 enregistrements au hasard mais pas les 100 derniers...

Donc il faut utiliser " id " et " desc "... mais où ?

Mais merci tu ma bien aidé et c'est pas urgent, j'imagine que tu doit être fatigué tu peut répondre quand tu veux :)
Bienvenue sur :
http://france.webmaster.fr.free.fr
Fabrication en cours...

Mammouth du PHP | 985 Messages

09 oct. 2009, 01:53

$sql = "SELECT texte,id FROM news ORDER BY Rand() DESC LIMIT 5";
Pas certain, donc quelqu'un va surement intervenir.
Mais tu peux toujours partir de cet exemple.
Face à la roche, le ruisseau l'emporte toujours, non pas par la force mais par la persévérance.

ViPHP
AB
ViPHP | 5818 Messages

09 oct. 2009, 02:55

Si tu n'y arrives pas directement dans la requête tu peux toujours faire un tableau avec les résultats puis le mélanger avec shuffle
$x_derniere_news = "5";
$sql = "SELECT texte,id FROM news ORDER BY id DESC LIMIT ".$x_derniere_news."";

$result = mysql_query($sql);

$tab_result = array();

while ($ligne = mysql_fetch_assoc($result))
{
$tab_result[] = $ligne;
}

shuffle($tab_result);

//vérification
echo '<pre>';
print_r($tab_result);
echo '</pre>';

Eléphanteau du PHP | 29 Messages

09 oct. 2009, 17:44

Bonjour AB, merci mais je n'arrive pas à intégrer ton code dans le mien :

Le code de base mélangé avec la requête de Dr@ke :
<?php

//-->> INCLUDE
include('mysql.php');

// Afficher les 100 dernières news...
$x_derniere_news = "100";

$sql = "SELECT texte,id FROM news ORDER BY RAND() LIMIT $x_derniere_news";
$req = mysql_query($sql) or die ('Erreur 0001 sur la page news_express.php'.mysql_error());

$message = 1;

while($data = mysql_fetch_assoc($req))
{
	$message = $message + 1;
	if($message == 2){$data['id'] = 0;}else{$data['id'] = $message - 2;}
	echo 'ejs_box2_message[';
	echo $data['id'];
	$data = str_replace("'","\'",$data['texte']);
	echo '] = \''.$data.'\';';
}

?>
puis ma tentative d'intégration de votre code :
<?php

//-->> INCLUDE
include('mysql.php');

// Afficher les 100 dernières news...
$x_derniere_news = "100";

$sql = "SELECT texte,id FROM news ORDER BY RAND() LIMIT $x_derniere_news";
$req = mysql_query($sql) or die ('Erreur 0001 sur la page news_express.php'.mysql_error());

// $tab_result = array();
// while ($ligne = mysql_fetch_assoc($req))
// {
// 	    $tab_result[] = $ligne;
// }
// shuffle($tab_result);

$message = 1;

while($data = mysql_fetch_assoc($req))
{
	$message = $message + 1;
	if($message == 2){$data['id'] = 0;}else{$data['id'] = $message - 2;}
	echo 'ejs_box2_message[';
	echo $data['id'];
	$data = str_replace("'","\'",$data['texte']);
	echo '] = \''.$data.'\';';
}

?>
Ce code incrémente un code JavaScript... d'où j'ai besoin du second while en fait ( je rappel que tout fonctionne ) il faut juste prendre les x derniers enregistrements et les mélanger par la suite (ce que fait le code de AB)...

Maintenant je cherche ( car je cherche aussi de mon coté ) comment les combiner... Pour le moment je fait plein de tests un peu hasardeux...
Bienvenue sur :
http://france.webmaster.fr.free.fr
Fabrication en cours...

ViPHP
AB
ViPHP | 5818 Messages

09 oct. 2009, 18:09

Si j'ai bien compris tu veux transférer ton tableau php dans un tableau javascript ?

Si oui tu gardes le tableau (dans mon exemple $tab_result que tu peux compléter si besoin) et tu te sert de json pour le transférer à javascript - si tes données encodées UTF-8 et que tu as minimum php version 5.2

Avec cette configuration (une raison de plus d'encoder en utf-8) c'est enfantin :

Code : Tout sélectionner

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Document sans titre</title> <?php echo '<script type="text/javascript"> var tab_js = ', json_encode($tab_result), '</script>'?>
Dans cet exemple le tableau php $tab_result a été transféré au tableau javascript tab_js

Eléphanteau du PHP | 10 Messages

10 oct. 2009, 22:11

Bonsoir,

Si je ne me trompe pas, au niveau SQL ça se fait de cette façon :
SELECT *
	FROM (
		SELECT texte, id
			FROM news
			WHERE 1
			ORDER BY id DESC
			LIMIT 5
		) AS lastest_records
	ORDER BY RAND( ) 
Ce qui donne : la première requête (celle qui est imbriquée) ressort les 5 derniers enregistrements et la seconde requête (celle qui encapsule) se charge de trier aléatoirement les résultats précédemment obtenus.

++

Eléphanteau du PHP | 29 Messages

10 oct. 2009, 23:29

Puissant !! Je savait pas que c'était possible d'imbriquer des requête dans d'autres :). Bon je n'est pas encore essayer, mais j'ai une question que signifie le " 1 " dans " ...WHERE 1 ORDER BY... " ?
Bienvenue sur :
http://france.webmaster.fr.free.fr
Fabrication en cours...

Eléphanteau du PHP | 29 Messages

10 oct. 2009, 23:36

Bon j'ai laisser le " 1 " sans avoir compris son rôle et j'ai fait le test ça fonctionne parfaitement !!!!

Vraiment très puissant cette astuce !! Bon je laisse le code au complet pour tout ceux qui veulent afficher des news de leur site :

Voici un aperçu : http://france.webmaster.fr.free.fr/news_express.php
<body bgcolor="#333232">

<body>
<DIV ID=ejs_box2_box STYLE="background-image:url(DESIGN/Copie%20de%20ok.png);color:#FFFFFF;font-family:Verdana;font-size:12;width:213;height:440;padding:5">
<p align="right"></DIV>
<SCRIPT LANGUAGE=JavaScript>
ejs_box2_message = new Array;

<?php

//-->> INCLUDE
include('mysql.php');

// Afficher les 20 dernières news...
$x_derniere_news = "3";

$sql = "SELECT * FROM ( SELECT texte, id FROM news WHERE 1 ORDER BY id DESC LIMIT $x_derniere_news ) AS lastest_records ORDER BY RAND( )"; // 100 au hasard mais pas les 100 derniers
$req = mysql_query($sql) or die ('Erreur 0001 sur la page news_express.php'.mysql_error());

$message = 1;

while($data = mysql_fetch_assoc($req))
{
	$message = $message + 1;
	if($message == 2){$data['id'] = 0;}else{$data['id'] = $message - 2;}
	echo 'ejs_box2_message[';
	echo $data['id'];
	$data = str_replace("'","\'",$data['texte']);
	echo '] = \''.$data.'\';';
}

?>

ejs_box2_actual = 0;
ejs_box2_html_flag = 0;

 function ejs_box2_go()
     {
     if(document.getElementById)
         {
         ejs_box2_char = 1;
         ejs_box2_affich(ejs_box2_actual)
         ejs_box2_actual++;
         if(ejs_box2_actual >= ejs_box2_message.length)
             ejs_box2_actual = 0;
         }
     }

 function ejs_box2_affich(lactual)
     {
     var pix = ejs_box2_message[lactual].charAt(ejs_box2_char);
     if(pix == "<")
         ejs_box2_html_flag = 1;
     if(pix == ">")
         ejs_box2_html_flag = 0;
     var texte = ejs_box2_message[lactual].substring(0,ejs_box2_char);
     document.getElementById("ejs_box2_box").innerHTML = texte;
     if(ejs_box2_char < ejs_box2_message[lactual].length)
         {
         ejs_box2_char++;
         if(ejs_box2_html_flag == 1)
             ejs_box2_affich(lactual);
         else
             setTimeout("ejs_box2_affich("+lactual+")",50)
         }
     else
         setTimeout("ejs_box2_go()",3000)
     }

 window.onload = ejs_box2_go;
 </SCRIPT>
 <!-- FIN DU SCRIPT --> 
</body>
CREATE TABLE IF NOT EXISTS `news` (
  `texte` longtext collate latin1_general_ci NOT NULL,
  `id` int(11) NOT NULL auto_increment,
  `texte_complet` longtext collate latin1_general_ci NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=22 ;
merci à Dr@ke, AB et à Shizu pour votre aide
Bienvenue sur :
http://france.webmaster.fr.free.fr
Fabrication en cours...

Eléphanteau du PHP | 10 Messages

11 oct. 2009, 01:10

Re,

Le "WHERE 1" dans ce cas là ne sert à rien. Tu peux l'enlever s'il te gêne. (Je me suis contenté d'éditer une requête générée par phpMyAdmin.)
En fait, il renvoie une condition qui est toujours vraie. (on pourrait même écrire "WHERE 1=1", ce qui a plus de sens mais "WHERE 1", c'est plus court ^^).
Un exemple d'utilisation : tu veux construire une requête en fonction de paramètres. le "WHERE 1" te servira de base et tu n'auras qu'à rajouter des clauses "AND table.truc = table2.muche" sans avoir à te soucier de savoir si c'est la première clause ou pas (donc si tu dois ajouter un "AND" ou pas).

C'était un plaisir d'aider =)

++

ViPHP
AB
ViPHP | 5818 Messages

12 oct. 2009, 17:51

Je suis passé à ton adresse pour voir. Tu as des petits pb d'encodage avec les caractères accentués. Un petit tuto ici.

Concernant ce topic, tu auras appris le fonctionnement des requêtes imbriquées ce qui est une bonne chose, et au passage l'utilité d'un "WHERE 1" qui est inutile dans ta requête (tu peux donc le supprimer) mais qui a toute son utilité dans cette remarque de shizu
Un exemple d'utilisation : tu veux construire une requête en fonction de paramètres. le "WHERE 1" te servira de base et tu n'auras qu'à rajouter des clauses "AND table.truc = table2.muche" sans avoir à te soucier de savoir si c'est la première clause ou pas (donc si tu dois ajouter un "AND" ou pas).
Sinon passer par une requête imbriquée simplement pour renvoyer un résultat aléatoire alors que tu as besoin de faire un tableau des résultats, et donc qu'un simple shuffle sur le tableau aurait produit le même résultat... ce n'est pas du tout certain que tu y gagne en performances, mais bon c'est un autre débat, au moins tu auras gagné en connaissances :)

Eléphant du PHP | 110 Messages

12 oct. 2009, 20:23

Sur ton site, par contre sa :
header('Content-type: text/html; charset=iso-8859-1');
Sa ferais pas de mal !