Classer des champs

Eléphant du PHP | 81 Messages

30 janv. 2007, 21:08

Bonjour a tous !

J'ai une table mySQL avec comme champs:
id | article | ordre

Ma requête : SELECT * FROM table ORDER BY ordre ASC

J’ai besoin de changer l'ordre d'affichage via une page d'admin et un système de flèche.
Lorsque je clique sur la flèche haute, mon article monte d’une position dans mon affichage.

Mon problème c’est que je n’arrive pas à trouver un système qui fonctionne correctement.

Quelqu’un connaît il un moyen simple de faire ce genre de classement ?

Merci

Eléphant du PHP | 81 Messages

31 janv. 2007, 11:17

Bonjour,

Y a vraiment personne qui à une solution ?

En fait pour mon administration je voudrais pouvoir classer mes articles comme je veux.
Avec un système de flèche je remonte ou descend mon article. Comme dans le CMS JOOMLA pou ceux qui connaissent.

Merci d’avance pour votre aide

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

31 janv. 2007, 11:43

Y a pas vraiment de solution simple à mettre en place. La plus logique consiste à intervertir les ordres de l'élément avec le précédent ou le suivant

A priori il te faut faire une requête pour aller chercher dans ta table :
- si tu remonte l'élément : l'ordre MAX inférieur à l'ordre de ton élément.
- si tu descend l'élément : l'ordre MIN supérieur à l'ordre de ton élément

Code : Tout sélectionner

SELECT MAX(ordre), id FROM table WHERE ordre < xxx ou SELECT MIN(ordre), id FROM table WHERE ordre > xxx
xxx étant l'ordre de l'élément courant

Mettre à jour l'élément trouvé avec l'ordre de l'élément courrant :

Code : Tout sélectionner

UPDATE ordre = xxx WHERE id = idElementTrouvé
Et enfin mettre à jour ton élément courrant avec la valeur de l'ordre de l'élément trouvé

Code : Tout sélectionner

UPDATE ordre = yyy WHERE id = idElementEnCours
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 81 Messages

31 janv. 2007, 13:04

merci pour cette piste,

Parcontre lorsque je fais la requêtte :

Code : Tout sélectionner

SELECT MAX(ordre), id FROM table WHERE ordre < xxx
J'ai comme erreur

Code : Tout sélectionner

Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL result resource
SI je fais comme requêtte :

Code : Tout sélectionner

SELECT MAX(ordre) AS id FROM table
Là ça fonctionne mais je n'ai pas le résultat que je veux.

Est ce la virgule qui pose problème ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

31 janv. 2007, 14:11

la virgule et le AS n'ont pas du tout la même fonction... moi je demande à récupérer les deux valeurs (le max et l'id associé) toi tu demandes le max et tu lui donne le libelle "id" comme alias...

Ce genre de message signifie que le résultat du mysql_query() ne correpond pas au résultat normal d'un select. On peut en déduire qu'il y a eu une erreur dans l'exécution du SQL.

ton champ s'appelle bien id ? tu as remplacé xxx par la valeur qui va bien ? que se passe-t-il si tu joues la requête généré dans mysql ou phpmyadmin ?
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 81 Messages

31 janv. 2007, 15:49

Voila la réponse dans phpmyadmin :
#1140 - Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause

Eléphant du PHP | 81 Messages

31 janv. 2007, 15:59

Si je fais cette requête dans phpmyadmin :

Code : Tout sélectionner

SELECT MAX( ordre ) FROM table WHERE ordre < xxx
Il me retourne NULL

ordre est de type (DATETIME)

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

31 janv. 2007, 16:24

ah flute, au temps pour moi... il faut passer par une sous requête et ramener dans un premier temps le max() et ensuite aller chercher l'id correspondant...

pourquoi un champ datetime ? si ordre est une position dans un classement, un simple int ne serait-il pas (ou ne devrait-il pas être) plus judicieux ?

Et quand tu fais "cette requête dans phpmyadmin", quelle valeur donnes-tu à xxx ??
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 81 Messages

31 janv. 2007, 16:43

Voici la valeur que je donne à xxx :

Lorsque je clique sur la flèche, je récupère l'id de l'article que je souhaite classer et ensuite je fais une requête :

Code : Tout sélectionner

$Num=$_GET['idnum']; $r="SELECT * FROM table where id='$Num'"; $rq=mysql_query($r); while($n=mysql_fetch_assoc($rq)){ $ordre=$n['ordre']; }
ensuite je fais ta requéte :
$f="SELECT MAX(ordre), id FROM table WHERE ordre<'$ordre'
J'utilise un DATETIME car c'est plus simple à envoyer dans la base lors de la soumission d'un nouvel article avec NOW(). Je sais que celui ci sera unique.

Comment dois je faire pour la sous requête ?

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

31 janv. 2007, 17:18

J'utilise un DATETIME car c'est plus simple à envoyer dans la base lors de la soumission d'un nouvel article avec NOW(). Je sais que celui ci sera unique.
Sauf le jour ou deux personnes enverront leur article en même temps et où tu auras deux date identiques. La fonction d'auto-incrémentation gère les accès concurents et ne retournera jamais deux fois la même valeur...

Pour la sous requête, si ta version de mysql le permet, il te suffit de faire ainsi :

Code : Tout sélectionner

SELECT id, ordre FROM table WHERE ordre = ( SELECT MAX(ordre) FROM table WHERE ... )
Si ta version de mysql ne le gère pas, il te suffit de décomposer en deux requêtes pour récupérer la valeur max de l'ordre, puis aller chercher l'id correspondant :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphant du PHP | 81 Messages

31 janv. 2007, 17:58

Là je patauge, je n’arrive pas à comprendre la logique pour décomposer la sous requête en 2 requêtes.
Peux tu m’aiguiller.

Est il possible d’avoir 2 champs en auto-incrémentation dans une table ?