Forum Clubic

Ordonnancement MySQL - Mettre en avant un média

Salut à tous,

Alors voilà j’ai besoin de faire un ordonnancement de lignes assez particulier dans mysql, c’est à dire que je veux pouvoir faire remonter un article déjà passé dans la BDD sans pour autant avoir à le réinsérer.

Concrètement voici un exemple de BDD


MEDIA ([U]id[/U], date, comments, user, rang);

Et quelques insertions :

MEDIA (4,12/04/06,test4,piokaz,0);

MEDIA (3,29/03/06,test3,piokaz,0);

MEDIA (2,18/03/06,test2,piokaz,0);

MEDIA (1,12/03/06,test,piokaz,0);

Je suis parti pour idée d’ordonnancer d’abord par rang et ensuite par l’id (ORDER BY rang ASC, id DESC)

Ma requête d’affichage d’origine avant que je ne mette le champ ‘rang’ : SELECT * FROM MEDIA ORDER BY id DESC LIMIT ,15

Sachant que j’aimerais par exemple pouvoir faire remonter l’id numéro 2 en premier je vais devoir mettre son rang à 1, du coup nouvel ordre (ceux de gauche affichés en premier) : 2,4,3,1, et que si je rajoute une autre entrée que l’ordre ne change pas : 5,2,4,3,1.

On peut appeler ça, mettre en avant un média déjà passé par exemple, et que si par la suite on rajoute une autre entrée, qu’il garde son ordre et ne revienne pas à la fin.

Je n’arrive pas trop à m’y retrouver, comment je dois gérer le champ ‘rang’ pour que cela se passe comme je veux.

Voilà, voilà mon message est peut-être un peu compliqué à comprendre, mais j’ai fait comme je pouvais.

Si vous pouviez me mettre de quelconque façon sur la voie… ou plus ou moins me dire à peu prés comment procéder…

Merci d’avance ( j’en ai vraiment besoin )

Dans ce cas là, je te proposerais la réflexion suivante:

Pourquoi un média mis en avant aurait un rang le plus petit possible?

Je m’explique.

Je suppose que ton champ ‘ID’ est croissant (compteur auto-incrémental ou un truc dans le genre). Ce qui signifie clairement, dans ce cas, que le média avec un ID le plus élevé possible appraît en tête de liste (order by id desc)

Bon, maintenant, imagine que ton champ ‘rang’ soit égal, au moment de l’insertion dans la base, au champ id.

Si je prends un exemple, ça donne ça:

MEDIA (6,12/04/06,test6,piokaz,6);
MEDIA (5,12/04/06,test5,piokaz,5);
MEDIA (4,12/04/06,test4,piokaz,4);
MEDIA (3,29/03/06,test3,piokaz,3);
MEDIA (2,18/03/06,test2,piokaz,2);
MEDIA (1,12/03/06,test,piokaz,1);

Dans ce cas, tu es d’accord, trier sur ‘id’ ou sur ‘rang’ reviens au même!

Bon, continuons. Maintenant, je décide de remonter un média en tête de liste (par exemple le n°2).

Dans ce cas, je pense que le plus judicieux est de récupérer l’id le plus élevé (6 dans l’exemple), et de l’insérer dans le champ ‘rang’ du média n°2

MEDIA (6,12/04/06,test6,piokaz,6);
MEDIA (5,12/04/06,test5,piokaz,5);
MEDIA (4,12/04/06,test4,piokaz,4);
MEDIA (3,29/03/06,test3,piokaz,3);
MEDIA (2,18/03/06,test2,piokaz,6);
MEDIA (1,12/03/06,test,piokaz,1);

A partir de là, il ne te reste plus qu’à trier ta table en prenant le chanp ‘rang’, puis le champ ‘id’ comme critère de tri:

un SELECT * FROM media ORDER BY rang DESC, id ASC devrait convenir (désolé si mes restes de SQL sont un peu vieillissants :smiley: )

On devrait obtenir le résultat suivant:
MEDIA (2,18/03/06,test2,piokaz,6);
MEDIA (6,12/04/06,test6,piokaz,6);
MEDIA (5,12/04/06,test5,piokaz,5);
MEDIA (4,12/04/06,test4,piokaz,4);
MEDIA (3,29/03/06,test3,piokaz,3);
MEDIA (1,12/03/06,test,piokaz,1);

Bien entendu, si tu veux rajouter une nouvelle entrée plus tard, ta table sera celle ci:

MEDIA (7,12/04/06,test7,piokaz,7);
MEDIA (6,12/04/06,test6,piokaz,6);
MEDIA (5,12/04/06,test5,piokaz,5);
MEDIA (4,12/04/06,test4,piokaz,4);
MEDIA (3,29/03/06,test3,piokaz,3);
MEDIA (2,18/03/06,test2,piokaz,6);
MEDIA (1,12/03/06,test,piokaz,1);

Et le résultat de la requete:

MEDIA (7,18/03/06,test7,piokaz,7);
MEDIA (2,18/03/06,test2,piokaz,6);
MEDIA (6,12/04/06,test6,piokaz,6);
MEDIA (5,12/04/06,test5,piokaz,5);
MEDIA (4,12/04/06,test4,piokaz,4);
MEDIA (3,29/03/06,test3,piokaz,3);
MEDIA (1,12/03/06,test,piokaz,1);

Bon, petite amélioration ou plutot débogage…

La réflexion ci-dessus peut poser problème si on désire remonter un article déja en tête de liste:

MEDIA (2,18/03/06,test2,piokaz,6);
MEDIA (6,12/04/06,test6,piokaz,6);
MEDIA (5,12/04/06,test5,piokaz,5);
MEDIA (4,12/04/06,test4,piokaz,4);
MEDIA (3,29/03/06,test3,piokaz,3);
MEDIA (1,12/03/06,test,piokaz,1);

Dans cet exemple (tiré du post précédent), si on veut remonter le média d’id 6 (placé en seconde position), ça pose problème, car la mise à jour du tuple ne va rien changer, le champ ‘rang’ restera à 6 vu que c’est le plus élevé :riva:

Dans ce cas, je pense qu’avant d’insérer un média, il faut rechercher le rang existant le plus élevé, et inscrire cette valeur+1 dans ‘rang’.

Exemple:

Etape 1, données initiales
MEDIA (6,12/04/06,test6,piokaz,6);
MEDIA (5,12/04/06,test5,piokaz,5);
MEDIA (4,12/04/06,test4,piokaz,4);
MEDIA (3,29/03/06,test3,piokaz,3);
MEDIA (2,18/03/06,test2,piokaz,6);
MEDIA (1,12/03/06,test,piokaz,1);

Etape 2, le média n°2 est remonté
MEDIA (2,18/03/06,test2,piokaz,7);
MEDIA (6,12/04/06,test6,piokaz,6);
MEDIA (5,12/04/06,test5,piokaz,5);
MEDIA (4,12/04/06,test4,piokaz,4);
MEDIA (3,29/03/06,test3,piokaz,3);
MEDIA (1,12/03/06,test,piokaz,1);

Etape 3, on ajoute un nouveau média
MEDIA (7,14/05/06,test7,piokaz,8);
MEDIA (2,18/03/06,test2,piokaz,7);
MEDIA (6,12/04/06,test6,piokaz,6);
MEDIA (5,12/04/06,test5,piokaz,5);
MEDIA (4,12/04/06,test4,piokaz,4);
MEDIA (3,29/03/06,test3,piokaz,3);
MEDIA (1,12/03/06,test,piokaz,1);

etc.

Ca devrait résoudre les problèmes!

Yahoooo !!
J’ai pas testé, mais ta logique semble sacrément correcte :smiley:

Et suite à ta seconde correction, (même si inutile) je ne pense pas que remonter un ID déja remonté servira à quelque chose…

Bon je vais aller faire quelques tests (oui j’ai pas encore testé :D)

Tu peux pas savoir comment tu me soulages d’une incompréhension… je te remercie… vraiment :slight_smile:

J’ai pas la tête à l’endroit ces derniers temps…

Sinon, au niveau de la vitesse d’execution de la requete, y’aura-t-il une grande différence ?

Merci

A quel niveau parles-tu de vitesse d’exécution?

Parce que la solution proposée est juste ‘purement’ algorithmique. La requête est la même que celle de ton premier post.

Pour le correctif, la requete est basique (SELECT max id FROM media ou un truc dans e genre), donc pas trop pénalisante à priori!

Pour la vitesse, je parle entre ces deux requetes :

SELECT * FROM media ORDER BY id DESC LIMIT 0,15

et

SELECT * FROM media ORDER BY rang DESC, id DESCLIMIT 0,15

Pour moi, je pense que la seconde prends plus de temps… mais j’ai pas les moyens de vérifier :confused:

Edit : En fait, mysql affiche le temps qu’il met pour executer la requete… et la seconde requete prend 3 fois plus de temps >_<, Bon c’est minime entre un 0.012 et 0.079, mais c’est quand même ça ^^

Heu,

Je peux affirmer un truc?

Au départ, tout tes éléments (medium?) sont au même rang, soit 0, ok ?

Ce que tu veux c’est en faire remonter certains au détriment d’autres?

Donc, à chaque fois qu’un élément doit remonter, tu fais un

SELECT MAX(rang) + 1 FROM table

Et tu modifie le rang avec la valeur du rang choisi, non?

(j’ai pas tout suivi de vos exemples, dsl)