Update +/-1 modifier seulement 2 enregistrements

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Update +/-1 modifier seulement 2 enregistrements

par FloBaoti » 18 mai 2007, 12:57

Merci beaucoup Hubert :lol: Super sympa :wink:

par Hubert Roksor » 18 mai 2007, 01:48

Je ne vois pas trop comment faire ça "facilement" (sans faire 3 ou 4 requetes)
A priori la méthode à 3 ou 4 requêtes semble être la plus simple et peut-être même la plus rapide (tu dois pas changer l'ordre de tes catégorie 10 fois par seconde non plus donc les performances ne sont pas très importantes). Enfin, en imaginant qu'on pense à la même méthode. (sans vouloir paraître trop désobligeant c'est le genre de trucs que tu aurais pu préciser pour éviter de tomber encore à côté)

Donc je résume l'algorithme pour faire monter une catégorie:
  • récupère le cat_ordre de la catégorie #123 (dans l'exemple, cat_order = 3)

    Code : Tout sélectionner

    SELECT cat_order FROM categories WHERE cat_id = 123
  • récupère le cat_id et le cat_order de la catégorie précédente (pour l'exemple : 456 et 2) en classant les catégories dans l'ordre (au passage ça nous permet de vérifier que la catégorie en question n'est pas déjà tout en haut)

    Code : Tout sélectionner

    SELECT cat_id, cat_order FROM categories WHERE cat_order < 3 ORDER BY cat_order DESC LIMIT 1
  • on ajoute les deux valeurs et on met à jour la base comme précédemment décrit

    Code : Tout sélectionner

    UPDATE categories SET cat_order = 5 - cat_order WHERE cat_id IN (123, 456)
Voilà, 3 requêtes simples. Mets un index sur cat_order, ça sert à classer les catégories extrêmement rapidement.

La même chose en 1 requête... ce n'est pas vraiment "plus simple"

Code : Tout sélectionner

UPDATE categories c JOIN ( SELECT c1.cat_id AS id1, c1.cat_order + c2.cat_order AS total, c2.cat_id AS id2 FROM categories c1 JOIN categories c2 ON c2.cat_order < c1.cat_order WHERE c1.cat_id = 123 ORDER BY c2.cat_order DESC LIMIT 1 ) AS tmp SET c.cat_order = tmp.total - c.cat_order WHERE c.cat_id IN (id1, id2)
PS: pour le faire marcher dans l'autre sens on remplace < par > et DESC par ASC

par FloBaoti » 17 mai 2007, 12:33

Quelqu'un aurait une petite idée s'il-vous-plait ?

par FloBaoti » 12 mai 2007, 13:31

désolé :oops: Merci à toi en tous cas :)

par Hubert Roksor » 12 mai 2007, 13:18

Le truc c'est que *normalement*, je ne connais que le champ cat_id de l'enregisterement
C'est typiquement le genre d'information qui aurait été utile dans ton premier message plutôt que de donner une requête qui n'a rien à voir...

Je repasserai sûrement sur le sujet un de ces quatres si tu ne trouves pas la solution entre-temps.

par FloBaoti » 12 mai 2007, 13:12

Désolé du retard, merci pour la réponse :wink:

Voilà la table:

Code : Tout sélectionner

CREATE TABLE `categories` ( `cat_id` tinyint(3) unsigned NOT NULL auto_increment, `cat_name` varchar(255) NOT NULL, `cat_url` varchar(255) NOT NULL, `cat_order` tinyint(3) unsigned NOT NULL, PRIMARY KEY (`cat_id`) )
Le truc c'est que *normalement*, je ne connais que le champ cat_id de l'enregisterement à monter ou descendre dans la liste (exemple, "monter d'une place l'enregistrement N°3").

Je ne vois pas trop comment faire ça "facilement" (sans faire 3 ou 4 requetes) ...

Merci d'avance si vous avez des idées :wink:

Flo.

par Hubert Roksor » 11 mai 2007, 03:40

Ce que tu peux faire, c'est intervertir l'ordre des deux "trucs", par exemple

Code : Tout sélectionner

SELECT SUM(ordre) AS total FROM table WHERE nom IN ('bla2', 'bla3')
Puis mettre à jour l'ordre à partir de la valeur de "total" (5 dans l'exemple)

Code : Tout sélectionner

UPDATE table SET ordre = 5 - ordre WHERE nom IN ('bla2', 'bla3')
Puisque tu sembles utiliser une versions de MySQL récente tu peux tout mixer avec une sous-requête telle que

Code : Tout sélectionner

UPDATE table AS t1, ( SELECT SUM(ordre) AS total FROM table WHERE nom IN ('bla2', 'bla3') ) AS t2 SET t1.ordre = t2.total - t1.ordre WHERE t2.nom IN ('bla2', 'bla3')
Ce n'est pas plus rapide à exécuter mais c'est plus court à taper. À toi d'adapter selon tes besoins/contraintes.

PS: j'ai pas testé les requêtes (mais je l'aurais fait si tu avais posté le CREATE TABLE qui va bien avec les INSERT qui vont avec, tu le sauras pour la prochaine fois ;)) donc une erreur peut subsister, à tester

Update +/-1 modifier seulement 2 enregistrements

par FloBaoti » 10 mai 2007, 17:37

Salut à tous,

Alors je voudrais faire un truc qui ne me parait pas extraordinaire mais qui me pose un petit problème.

J'ai une table du genre:
nom, ordre
bla1, 1
bla2, 2
bla3, 3
bla4, 4
bla5, 5


Et je voudrais modifier le champ ordre en faisant +1 à un enregistrement, et -1 à un autre.
Par exemple si je veux classer bla3 avant bla2, je fais +1 à bla2 et -1 à bla3.

J'ai essayé ça:

Code : Tout sélectionner

UPDATE table t1, table t2 SET t1.ordre=t1.ordre-1, t2.ordre=t2.ordre+1 WHERE t1.nom='bla3' AND t2.ordre=t1.ordre+1
Mais ça me modifie 3 enregistrements ! Je suppose que c'est parce que t1.ordre est modifié, ça fait une fois la requete avant de modifier et une fois modifié.
Evidemment, il ne veux pas entendre parler de LIMIT...

Est-ce que vous avez une idée, comment faire ça en une requete ?

Merci beaucoup par avance!

Cordialement,
Flo.