[Résolu] Pb de tri sur un varchar (Mysql)

Pb de tri sur un varchar (Mysql) [Résolu] - SQL/NoSQL - Programmation

Marsh Posté le 02-01-2012 à 11:03:33    

Bonjour,
 
Moi aussi j'ai un pb pour le tri de certains record sur un champ qui est un varchar, dont les données sont de ce style :
ID  |  NOrder
1   |  1
2   |  2
3   |  1-1
4   |  1-2
5   |  3
6   |  2-1
7   |  3-1
...
 
NOrder contient un code en fonction de la position du record dans une arborescence. En gros, je voudrais à la sortie :
1
1-1
1-2
2
2-1
3
3-1
...
 
Un simple ORDER By NOrder marche tant que le premier nombre est compris entre 1 et 9. Mais à partir de 10, ben j'ai  
1
1-1
1-2
10
10-1
...
2
2-1
3
3-1
...
 
Je suis sous MySQL 5. Y'aurait une solution pas trop lourde pour résoudre mon pb, svp?
 
Merci :)


Message édité par rufo le 05-01-2012 à 16:47:50

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 02-01-2012 à 11:03:33   

Reply

Marsh Posté le 03-01-2012 à 08:12:09    

Le probleme c'est que c'est un ordre alphabetique correct, a mon avis la facon la plus facil d'eviter le probleme est d'ajouter des 0 devant pour avoir un chiffre sur x caractères.
 
Au lieu de 1-1, 1-2 et 10-1 tu aurais 01-01, 01-02 et 10-01. Et la tu ne devrais plus avoir de problemes de sort.

Reply

Marsh Posté le 03-01-2012 à 10:03:14    

Rajouter un 0 n'est pas vraiment possible car le nb d'enregistrements ne fait que croître, je ne peux donc pas savoir s'il faut rajouter 1, 2 voire 3 zéro :(...
 
Je chercherais plus un algo travaillant sur le champ NOrder (en splittant sur les "-", par ex...)


Message édité par rufo le 03-01-2012 à 10:25:23

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 03-01-2012 à 11:07:07    

question indiscrete : pourquoi tu utilises ce systeme?
 
si c'est pour faire une arborescence ce n'est pas la meilleure methode (ni la plus simple) pour ca il y a les intervallaires.
 
dans tous les cas la solution adaptée depend de la profondeur de ton NOrder parce que la solution generique que je pense que tu cherche c'est une requete moisie ou tu split et tu multiplie/trie plusieurs fois avec une complexité logarithmique donc lourde.


---------------
[VDS] rail vesa, bras ecran, support TV / [ACH] des machins
Reply

Marsh Posté le 03-01-2012 à 13:05:09    

pop-pan a écrit :

question indiscrete : pourquoi tu utilises ce systeme?
 
si c'est pour faire une arborescence ce n'est pas la meilleure methode (ni la plus simple) pour ca il y a les intervallaires.
 
dans tous les cas la solution adaptée depend de la profondeur de ton NOrder parce que la solution generique que je pense que tu cherche c'est une requete moisie ou tu split et tu multiplie/trie plusieurs fois avec une complexité logarithmique donc lourde.


 
Pour les arbos, en BD, tu as effectivement la représentation intervallaire (très bien si y'a surtout des accès en lecture, mais pourrie si on fait surtout de l'insertion) et la représentation via un ParentID (représentation que j'ai choisie qui a les avantages/inconvénients inverse de l'intervallaire). Le champ "NOrder" ne contient qu'une info de type "communication".
 
En temps normal, mon système ne pose pas de pb car les enregistrements sont créés dans l'ordre chronologique. En faisait un order by sur leur ID et leur NOrder, j'avais le bon ordre. Mais dans un autre contexte d'utilisation où l'ordre de création n'a pas d'importance, là, ça pose un pb :/


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 03-01-2012 à 16:32:40    

C'est le meme principe que le HierarchyId dans SQL Server: http://technet.microsoft.com/en-us [...] 77290.aspx
 
Regarde comment ils l'ont implementé et peut etre que tu trouveras quelque chose qui t'inspirera :)
 
Ils utilisent des bits, donc ca devrai pouvoir aussi se faire pour toi. Si tu utilises 2 bytes par nodes ca te fais un max de 65535 et si tu passes a 4 ca t'en fais ~4milliards. Avec un nombre fix de bytes ca devrai etre assez rapide a parser et l'ordre sera toujours correct. Ce sera aussi super compact.


Message édité par Oliiii le 03-01-2012 à 16:33:02
Reply

Marsh Posté le 03-01-2012 à 17:22:51    

Si tu n'as pas de 1-2-3 :
 
CAST( REPLACE( NOrder, '-', '.' ) AS BINARY )
1
1.1
1.2
2
2.1
3
3.1  
10
10.1
...


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 03-01-2012 à 17:32:06    

Erreur de ma part, BINARY ne marchera pas du tout ! ! !


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 04-01-2012 à 10:27:37    

Mara's dad a écrit :

Si tu n'as pas de 1-2-3 :
 
CAST( REPLACE( NOrder, '-', '.' ) AS BINARY )
1
1.1
1.2
2
2.1
3
3.1  
10
10.1
...


 
Si je peux avoir 1-1-1-1-... Cela dit, ton idée m'a mis sur la piste d'une autre. Je récupère le niveau de profondeur dans l'arbo le plus profond (en gros, le NOrder qui a le plus de "-" ) et je construis un polynôme ax^n+bx^(n-1)....+z où a, b, c,...z vont prendre les valeurs sépares les "-" de leur NOrder. J'aurais qu'à faire un order by sur le résultat du calcul... Pour simplifier, je peux dire arbitrairement que j'aurais jamais plus de N niveaux de profondeur (par ex N= 10, ce qui est déjà énorme) et j'ai juste à calculer le polynôme ;)


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 04-01-2012 à 13:59:13    

Si qq'un a mieux à proposer, je suis preneur. Sinon, je passe en [résolu] mon topic.


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 04-01-2012 à 13:59:13   

Reply

Marsh Posté le 04-01-2012 à 16:14:06    

ben c'etait ce que j'allais proposer, le split et le mul au cas ou la profondeur max est *faible*. c'est toujours pareil, si on borne pas ca devient compliqué.
sinon le cast binary sur les split c'est pas con non plus mais c'est pas forcement plus malin que de faire un lpad(), par contre dans ce cas il faut connaitre la valeur max des element.
 
si tu peux rajouter un champ autant faire un lpad lors de l'insertion , genre '0001-0010-0002' comme ca c'est fait.
 
sinon un code moisi vite fait basé sur des commentaires mysql qui devrait faire la meme chose => http://dev.mysql.com/doc/refman/5. [...] tions.html (enfin presque ca retourne "-0001-0010-0002" au lieu de "0001-0010-0002" mais pour un sort ca marchera)
sachant que faudra modifier des trucs genre le return type si ca depasse.
 

Code :
  1. CREATE FUNCTION norder(in varchar(255)) returns varchar(255)
  2. BEGIN
  3. DECLARE out varchar(255);
  4. DECLARE count INT(1);
  5. DECLARE inc INT(1);
  6. SET out = '';
  7. SET count = (length(in)-length(replace(in, '-', '')))+1;
  8. SET inc=0;
  9. WHILE (inc < count) DO
  10. SET out = concat_ws('-',out,LPAD(quote(replace(substring(substring_index(in, '-', inc+1), length(substring_index(in, '-', inc)) + 1), '-', ''))),4,'0');
  11. SET inc = inc + 1;
  12. END WHILE;
  13. RETURN out;
  14. END


Message édité par pop-pan le 04-01-2012 à 16:18:01

---------------
[VDS] rail vesa, bras ecran, support TV / [ACH] des machins
Reply

Marsh Posté le 05-01-2012 à 16:47:10    

En fait, je fais d'abord une détection du max de la profondeur de mon arbo, ensuite, je construis ma requête sql pour faire le calcul des coeff du polynôme (en fait, faut prendre des 10^n).


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 05-01-2012 à 17:27:45    

avec un lpad tu n'as pas a calculer de coefs


Message édité par pop-pan le 05-01-2012 à 17:28:08

---------------
[VDS] rail vesa, bras ecran, support TV / [ACH] des machins
Reply

Marsh Posté le 05-01-2012 à 18:03:26    

Effectivement, ton approche est intéressante, surtout en terme de perfs, pas besoin de faire des multiplications et calculer des 10^n ;)
 
Merci!


Message édité par rufo le 05-01-2012 à 18:03:54

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed