Bonjour,
j’aimerai sélectionner les x derniers enregistrements d’une table. Lorsque le tri est décroissant, je n’ai aucune difficulté mais en tri croissant, je ne sais pas comment faire car ça sélectionne les x premiers et non les x derniers). J’ai bien tenté d’écrire limit -x mais ça ne marche pas. J’ai aussi tenté de regarder dans la doc de mysql mais elle est indigeste.
Voici ma requète avec x = 50 et tri décroissant.
SQL
[color=blue;font-weight:bold]SELECT[/color] * FROM `srw_wars` WHERE `v` = '19-1' AND `user` = '1' ORDER BY `date` DESC LIMIT 0, 50;
[color=blue;font-weight:bold]SELECT[/color] * FROM `srw_wars` AS T WHERE `v` = '19-1' AND `user` = '1' ORDER BY `date` ASC LIMIT (COUNT(T.id)-50), 50;
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘(COUNT(T.id)-50), 50’ at line 1 :neutre:
Je dis peut-etre une betise mais ça me parait normal en fait.
Dans ta requete, tu mets un limit à 0, 50
Donc tu lui demande de partir de 0 et de prendre les 50 enregistrement suivant.
Donc forcément en mode décroissant ça marche, mais en mode croissant… il va prendre les 50 premiers.
Il faudrait faire un count de l’ensemble, enlever 50 et faire un limit XX (ou XX représente le chiffre du count moins les 50 derniers enregistrement)
C’est ce que benj a essayé de traduire en requete je pense.
Moi je me serais fais chier à faire deux requetes (ou une requete + sous-requete) une qui compte et l’autre qui selectionne
[color=blue;font-weight:bold]SELECT[/color] *, count(T.id) AS N FROM `srw_wars` AS T WHERE `v` = '19-1' AND `user` = '1' ORDER BY `date` ASC LIMIT (N-50), 50;
Mais erreur : ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘(N-50), 50’ at line 1
Etant donné que je récupère les résultats dans php, je ne peux faire “qu’une requète par requète” (je me comprend).
C’est vrai que je pourrai faire une requète au préable pour déterminer le nombre d’entrées… Je vais tenter mais j’aimerai faire un minimum de requètes (j’en ai déjà énormément)…
Je comprend tout à fait le principe de “une requete par requete”, j’utilise la meme méthode faute d’etre un expert en SQL
Essais avec une requete supplémentaire… c’est ce que j’aurais fait pour avoir le count global moins les cinquantes dernier enregistrement.
Je reconnais que c’est “lourd” mais ayant oublié une grande partie de mes cours SQL de l’époque, je ferais pas mieux :lol:
[color=blue;font-weight:bold]SELECT[/color] *, count(T.id)-50 AS N FROM `srw_wars` AS T WHERE `v` = '19-1' AND `user` = '1' ORDER BY `date` ASC LIMIT N, 50;
[color=blue;font-weight:bold]SELECT[/color] *, count(T.id)-50 AS N FROM `srw_wars` AS T WHERE `v` = '19-1' AND `user` = '1' ORDER BY `date`ASC LIMIT N, 50;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘N, 50’ at line 1
SQL
[color=blue;font-weight:bold]SELECT[/color] *, (count(T.id)-50) AS N FROM `srw_wars` AS T WHERE `v` = '19-1' AND `user` = '1' ORDER BY `date` ASC LIMIT N, 50;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘N, 50’ at line 1
Ce qu’il a pas l’air d’aimer c’est que l’on mette autrechose qu’un nombre dans la limite.
En attendant, je fais deux requètes mais j’aimerai ne pas rester sur une bète requète. Voici un petit extrait de mon php en attendant (il fonctionne).
$count = q('SELECT COUNT(id) AS `n` FROM `srw_'.strtolower($what).'` WHERE `v` = \''.$v.'\' AND `user` = \''.$joueur.'\';', $con);
$count = mysql_fetch_array($count);
$count = $count['n'];
if ($nbr == 'all') $limit = '';
else if (preg_match('!^[0-9]+$!', $nbr)) $limit = ' LIMIT '.((($count-$nbr) > 0) ? ($count-$nbr) : 0).', '.$nbr;
else $error = true;
if (!$error) {
$q = 'SELECT * FROM `srw_'.strtolower($what).'` WHERE `v` = \''.$v.'\' AND `user` = \''.$joueur.'\' ORDER BY `'.strtolower($tri).'` ASC'.$limit.';';
//echo $q;
$q = q($q, $con) or die(mysql_error());
$n = mysql_num_rows($q);
if ($n == 0) return '<p>Rien. </p>';
else {
En lisant la doc MySQL j’ai vu qu’il était possible de créer des variables temporaires utilisables dans les requètes. Je vais aller refaire un tour la dedans… :sarcastic:
Peut etre que Sans-Pseudo passera par là. :pt1cable:
SET @skip=SELECT count(`srw_wars.id`)-50 from `srw_wars`; SET @numrows=50;
PREPARE func FROM 'SELECT * FROM `srw_wars` AS T WHERE `v` = '19-1' AND `user` = '1' ORDER BY `date` ASC LIMIT ?, ?';
EXECUTE func USING @skip, @numrows;
Oui, c’est ça que je souhaite faire.
J’ai essayé quelque chose de similaire à ta proposition avant de poster ici.
L’idée est donc dans un premier temps de sélectionner les 50 derniers par ordre descendant puis de les réordonner.
La première partie fonctionne mais lorsque je refais le tri, la requète plantouille et prend tous les enregistrements par ordre descendant.
Saluton,
A ma connaissance, MySQL n’accepte pas de clause ORDER BY dans un sub-select.
Mais je pense qu’il doit y avoir moyen d’obtenir ce que tu veux en demandant à MySQL de numéroter les enregistrements par à une jointure réflexive sur la table.
Je vais y réfléchir.
Euh faut pas faire quelque chose de trop complexe car il y aura entre 0 et 1000 enregistrements qui pourront être retournés…
Par contre je ne comprend pas que ça puisse posez autant de problèmes pour une requète aussi simple… Ce qui aurait été bien ça serait de mettre un nombre négatif pour la limite mais c’est trop demander pour MySQL…
Bon moi vais réviser : épreuves de TP pour le bac demain.
Bien j’ai du mal à faire fonctionner ça en command line. Le problème c’est que j’exploite les résultats avec PHP donc je ne peux faire qu’une seule requète par requète… Même si je tentais avec plusieurs mysql_query(), ça sera encore plus gros que ma solution de remplacement en 2 requètes (une compte, l’autre récup).
Je vais quand même tenter la chose…
Bon finalement, je te suggères de déporter le problème de SQL vers le L4G support ce qui donne, par exemple sous PHP/MySQL.
Voici ce que j’ai testé sur une table d’uen de mes bases en local
<pre>
<?php
error_reporting(E_ALL);
$serveur="~~~~";
$user="~~;
$DBpwd="";
$nomDB="~~~~~~";
$conn=mysql_connect($serveur,$user,$DBpwd)or die(mysql_error());
mysql_select_db($nomDB,$conn)or die(mysql_error());
$sql = "SELECT code, client, date_commande, CONCAT(jourdepart,' ', heuredepart) AS rang FROM commandes
ORDER BY rang DESC LIMIT 3";
$req=mysql_query($sql);
$res=array();
while($res[]=mysql_fetch_assoc($req)){}
array_splice($res,-1,1);
$res=array_reverse($res);
print_r($res);
mysql_close();
?>
</pre>