Dams Posté 8 Octobre 2004 Posté 8 Octobre 2004 (modifié) Bonjour, Je souhaiterai numéroter les lignes d'une table en fonction d'un ordre particulier... Cela équivaut à un : SELECT `id` FROM `mytable` ORDER BY (Mon tri ) Avec `id` unique bien sur.. Et pour chaque ligne je fait un: UPDATE `mytable` SET `numero`=$I WHERE `id`=$id Super pour quelques milliers d'enregistrement.... Mais pour plusieurs millions Ca fait plusieurs millions de requête+1 Quelqu'un connaîtrai t'il le moyen de la faire en 1 requête ??? Merci à toi qui va me permettre d'econnimiser mon CPU Modifié 8 Octobre 2004 par Dams
Anonymus Posté 8 Octobre 2004 Posté 8 Octobre 2004 Comme ca, ca devrait aller : UPDATE mytable SET numero=numero+1 WHERE id=$id
Dams Posté 8 Octobre 2004 Auteur Posté 8 Octobre 2004 Si tu fait ca tu incremente la valeur numero... Tu n'a pas des champs numeroté du type 1 2 3 4 Un exemple réél de ce que je veux: Prenons ma base des 720 000 sites Yoovi... J'ai une table des 72000 sites avec comme champs POSIT (La position) iddom L'id unique du domaine score Le score... Je rempli la table en une seule requete en renseignant iddom et score... Mais la postion n'est pas determiné... Je fait un: SELECT iddom FROM `matable` ORDER BY `score` Et derriere je fait des UPDATE sur position dans une boucle... Avec la position incrementé a chaque passage Trop long
Berberber Posté 8 Octobre 2004 Posté 8 Octobre 2004 jette un coup d'oeuil à cette discussion, je pense avoir eu le même problème que toi : http://www.webmaster-hub.com/index.php?showtopic=6217
thewiseoldman Posté 8 Octobre 2004 Posté 8 Octobre 2004 Je ne vois pas comment faire si ce n'est avec les fonctions mysql_insert_id ou LAST_INSERT_ID() voir http://fr.php.net/mysql_insert_id pour de plus amples informations. L'idée est donc de récupérer l'id ou numéro de l'enregistrement courant du résultat. Trié sur le score descendant, le premier résultat aura l'id 1 qui correspond à sa position, je sais pas si je suis clair
Sarc Posté 8 Octobre 2004 Posté 8 Octobre 2004 Je ne pense pas que tu puisses faire cela en une seule requete... j'ai beau chercher, je ne vois pas ! Vu qu'il y a forcément une clause "where", tu ne peux le faire que d'une requete a une requete :s Enfin, si j'ai une idée sublime dans la nuit, je te dis ca demain
Dams Posté 9 Octobre 2004 Auteur Posté 9 Octobre 2004 Merci ca me donne des pistes Je planche sur tout ca !!! Et je reviens
petit-ourson Posté 9 Octobre 2004 Posté 9 Octobre 2004 Dans une sélection, on a un moyen de savoir sur quel ligne on se trouve ?
petit-ourson Posté 9 Octobre 2004 Posté 9 Octobre 2004 (modifié) Soit ma table MESVILLES avec les champs suivants VILLE, POPULATION. SELECT * FROM MESVILLES ORDER BY POPULATION On obtient une liste des villes classée par population. Créons une nouvelle table MESVILLESCLASSEES avec comme champ supplémentaire un auto_increment de type int que l'on nommera CLASSEMENT Il nous reste à effectuer la requête suivante : INSERT INTO MESVILLESCLASSEES (VILLE,POPULATION) SELECT * FROM MESVILLES ORDER BY POPULATION Nous nous retrouvons ainsi avec une tables MESVILLES sans classement et une table MESVILLESCLASSEES avec un champ supplémenaire correspondant un classement. NB: Ca fonctionne sous MySQL et je pense que ca doit fonctionner ailleurs car ça me semble normaliser comme insert (mais à vérifier). EDIT: J'aurai du supprimer l'autre mais je trouve pas où cela se passe :-( Modifié 9 Octobre 2004 par petit-ourson
Anonymus Posté 9 Octobre 2004 Posté 9 Octobre 2004 Il me semble que les 'sous-requetes' ne marchent pas, avec mysql, mais ca vault la peine d'être essayé. Tu devrais aussi jeter un oeil à ceci : http://www.dwam.net/docs/mysql3.23/manuel_...t-rollback.html Ca explique notamment pourquoi mysql est 2 à 4 fois plus rapide que bien d'autres sql, mais pourrait aussi te donner des 'tuyaux' pour ton 'casse tete'
petit-ourson Posté 9 Octobre 2004 Posté 9 Octobre 2004 (modifié) J'ai testé avec un exemple et sous mysql 4.0.18, ça fonctionne. Comme je n'ai rien inventé voici ma source : 14.1.4.1 Syntaxe de INSERT ... SELECT Modifié 9 Octobre 2004 par petit-ourson
Dams Posté 11 Octobre 2004 Auteur Posté 11 Octobre 2004 Si si ca marche les sous requetes.. je les utilisent tous les jours, mais sous mysql 4 En fait la question est comme le dit petit-ourson de savoir si: Dans une sélection, on a un moyen de savoir sur quel ligne on se trouve J'ai pas encore trouvé...
Anonymus Posté 11 Octobre 2004 Posté 11 Octobre 2004 ... Pour ceux qui ne mettent pas de champs auto_increment, il reste la solution : mysql_field_seek(PHP 3, PHP 4 , PHP 5) mysql_field_seek -- Déplace le pointeur de résultat Description int mysql_field_seek ( resource result, int field_offset) Place le pointeur de résultat sur le champ spécifié. Lors du prochain appel à mysql_fetch_field() qui n'aura pas d'argument d'index de champ, le champ désormais pointé sera retourné. Voir aussi mysql_fetch_field(). Bon courage
Dams Posté 11 Octobre 2004 Auteur Posté 11 Octobre 2004 (modifié) Dans mon cas je n'utilise pas php Je réalise directement les requêtes sur le serveur mysql Modifié 11 Octobre 2004 par Dams
thewiseoldman Posté 11 Octobre 2004 Posté 11 Octobre 2004 Ca ne sera pas possible alors, sauf si la table est recrée à chaque changement du classement, avec un auto increment sur le champ position, la table devra être recréée avec les enregistrements déjà triés sur le score descendant.
petit-ourson Posté 11 Octobre 2004 Posté 11 Octobre 2004 (modifié) Et ca n'a pas marché mon exemple en passant par une table temporaire ? C'est pas ce que tu voulais ? Modifié 11 Octobre 2004 par petit-ourson
Dams Posté 11 Octobre 2004 Auteur Posté 11 Octobre 2004 Je pense qu'on tiens la soluce Passer par 1 table temporaire avec le champs position en auto increntation c'est le top.... On a besoin de 4 requetes Mais c'est acceptable... 1) Création de la table temporaire 2) Insertion des valeurs de la table a trier vers la Table temporaire. 3) Supression de la table Originale 4) Renommer la table temporaire en table principale...
Anonymus Posté 11 Octobre 2004 Posté 11 Octobre 2004 Inverses le 3) et le 4). Si jamais ca plante entre les 2, tu auras toujours une table 'valide'. table_ok => table_bak table_temp => table_ok
Sujets conseillés
Veuillez vous connecter pour commenter
Vous pourrez laisser un commentaire après vous êtes connecté.
Connectez-vous maintenant