Partage
  • Partager sur Facebook
  • Partager sur Twitter

SELECT avec tri par nom

Besoin d'aide

    30 août 2011 à 23:31:37

    Bonjour,

    J'ai une base de données MySQL et j'aimerai sélectionner une table entièrement alors voici ma requète

    "SELECT * FROM table ORDER BY name ASC"


    Cependant, les enregistrement dans le champ name sont de ce type :

    - Name 1
    - Name 2
    - Name 10

    Et donc, le tri se fait de la sorte :

    - Name 1
    - Name 10
    - Name 2

    J'aimerai donc trier cela normalement, sans passer par le PHP, uniquement en modifiant ma requête.

    Je vous remercie d'avance,

    Bonne soirée.
    • Partager sur Facebook
    • Partager sur Twitter
      30 août 2011 à 23:51:47

      C'est trié normalement. Si tu ne veux pas trier les chaînes de caractères, utilise une autre colonne (genre, une colonne auto-incrémentée).
      • Partager sur Facebook
      • Partager sur Twitter
        31 août 2011 à 0:24:22

        Je veux trier sur la chaine de caractères justement, mais comme je l'ai dit précédemment le "Name 10" passe avant le "Name 2".
        • Partager sur Facebook
        • Partager sur Twitter
          31 août 2011 à 0:24:50

          Oui, et c'est exactement le comportement attendu. Quel est le problème ?
          • Partager sur Facebook
          • Partager sur Twitter
            31 août 2011 à 8:54:10

            Moi j'aimerai justement que le "Name 2" passe avant le "Name 10" c'est gérable en modifiant la requête SQL ?
            • Partager sur Facebook
            • Partager sur Twitter
              31 août 2011 à 11:30:22

              Je comprends pas, je pose une question, j'attends une réponse ou des pistes, toi tu me réponds par une autre question
              • Partager sur Facebook
              • Partager sur Twitter
                31 août 2011 à 11:31:46

                Peut-être y a-t-il une raison à ma question, mais bon, laisse tomber.
                • Partager sur Facebook
                • Partager sur Twitter
                  31 août 2011 à 11:33:43

                  Ils proviennent d'enregistrements automatiques, je pense que tu allais me suggérer de mettre un 0 devant les nombres à un chiffre mais c'est une solution que j'ai exclue ;)
                  • Partager sur Facebook
                  • Partager sur Twitter
                    31 août 2011 à 11:50:38

                    Non, j'allais te suggérer de les mettre à part dans une colonne de tyoe INT.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      31 août 2011 à 12:05:52

                      Merci pour ta suggestion,

                      Mais je ne peux malheureusement pas toucher à la structure de données.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        31 août 2011 à 19:42:09

                        Citation : vtom

                        Je comprends pas, je pose une question, j'attends une réponse ou des pistes, toi tu me réponds par une autre question


                        Ta question a déjà été résolue, donc je vois mal où tu veux en venir.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          1 septembre 2011 à 21:39:55

                          je vais plutôt présumer que c'est des données style des noms de fichier, où il peut y avoir n'importe quoi, donc c'est pas faisable de mettre les entiers dans des colonnes int... mais on aimerait quand même que les 50 .rar .r01 etc de notre dernier téléchargement légal s'affichent dans l'ordre, ou un truc du genre !...

                          google => natural sort

                          Une stratégie stupide mais fonctionnelle est d'utiliser une regexp pour remplacer les nombres dans la string. Par exemple tu rajoutes autant de zéros qu'il faut ou des espaces. Avec une vraie BDD ce serait réglé :

                          -- SQL déguisé en perl
                          CREATE FUNCTION natcasekey(name TEXT) RETURNS TEXT[] AS $$ 
                          SELECT array( 
                            SELECT CASE WHEN t ~ E'\\d+' THEN lpad(t,12) ELSE t END 
                            FROM regexp_split_to_table( trim( regexp_replace( $1, E'([0-9](?=[^0-9])|[^0-9](?=[0-9]))', E'\\1 ', 'g' )), E'\\s+' ) t ); 
                          $$ LANGUAGE SQL;
                          
                          CREATE TEMPORARY TABLE popo ( t TEXT );
                          INTO popo SELECT 'a'||((random()*20)::INTEGER)||'b'||((random()*20)::INTEGER) FROM generate_series(1,20);
                          
                          SELECT * FROM popo;
                             t    
                          --------
                           a1b3
                           a12b6
                           a5b19
                           a4b7
                           a5b13
                           a8b12
                           a4b12
                           a18b9
                           a14b6
                           a15b19
                           a13b1
                           a7b5
                           a14b16
                           a5b10
                           a16b12
                           a7b17
                           a14b20
                           a3b20
                           a19b6
                           a6b4
                          (20 lignes)
                          
                          SELECT * FROM popo ORDER BY natcasekey(t);
                             t    
                          --------
                           a1b3
                           a12b6
                           a13b1
                           a14b16
                           a14b20
                           a14b6
                           a15b19
                           a16b12
                           a18b9
                           a19b6
                           a3b20
                           a4b12
                           a4b7
                           a5b10
                           a5b13
                           a5b19
                           a6b4
                           a7b17
                           a7b5
                           a8b12
                          (20 lignes)
                          
                          SELECT *, natcasekey(t) FROM popo ORDER BY natcasekey(t);
                             t    |             natcasekey              
                          --------+-------------------------------------
                           a1b3   | {a,"           1",b,"           3"}
                           a12b6  | {a,"          12",b,"           6"}
                           a13b1  | {a,"          13",b,"           1"}
                           a14b16 | {a,"          14",b,"          16"}
                           a14b20 | {a,"          14",b,"          20"}
                           a14b6  | {a,"          14",b,"           6"}
                           a15b19 | {a,"          15",b,"          19"}
                           a16b12 | {a,"          16",b,"          12"}
                           a18b9  | {a,"          18",b,"           9"}
                           a19b6  | {a,"          19",b,"           6"}
                           a3b20  | {a,"           3",b,"          20"}
                           a4b12  | {a,"           4",b,"          12"}
                           a4b7   | {a,"           4",b,"           7"}
                           a5b10  | {a,"           5",b,"          10"}
                           a5b13  | {a,"           5",b,"          13"}
                           a5b19  | {a,"           5",b,"          19"}
                           a6b4   | {a,"           6",b,"           4"}
                           a7b17  | {a,"           7",b,"          17"}
                           a7b5   | {a,"           7",b,"           5"}
                           a8b12  | {a,"           8",b,"          12"}
                          


                          donc c'est simple il suffit de découper le truc en morceaux et de pad les entiers avec des espaces !

                          évidemment c'est extrêmement lent, enfin on peut toujours matérialiser le résultat de la fonction dans une colonne...

                          test=> EXPLAIN ANALYZE SELECT * FROM popo ORDER BY t;
                                                                        QUERY PLAN                                              
                          ------------------------------------------------------------------------------------------------------
                           Sort  (cost=1.63..1.68 rows=20 width=6) (actual time=0.036..0.038 rows=20 loops=1)
                             Sort Key: t
                             Sort Method:  quicksort  Memory: 25kB
                             ->  Seq Scan on popo  (cost=0.00..1.20 rows=20 width=6) (actual time=0.003..0.004 rows=20 loops=1)
                           Total runtime: 0.059 ms
                          
                          test=> EXPLAIN ANALYZE SELECT * FROM popo ORDER BY natcasekey(t);
                                                                        QUERY PLAN                                              
                          ------------------------------------------------------------------------------------------------------
                           Sort  (cost=6.63..6.68 rows=20 width=6) (actual time=1.595..1.597 rows=20 loops=1)
                             Sort Key: (natcasekey(t))
                             Sort Method:  quicksort  Memory: 27kB
                             ->  Seq Scan on popo  (cost=0.00..6.20 rows=20 width=6) (actual time=0.215..1.460 rows=20 loops=1)
                           Total runtime: 1.617 ms
                          


                          Bon, revenons à mysql (lol) qui n'offre aucune fonctionnalité décente en matière de regexp donc à moins de faire une boucle caractère par caractère dans une procédure stockée (lol) c'est mort.

                          Il ne te reste plus qu'à stocker le nom transformé dans une colonne supplémentaire en rajoutant les espaces devant les nombres, ce qui prend une ligne de code php (avec preg_replace_callback) ou python, mais comme tu peux pas le mettre dans un trigger, il se tiendra pas à jour tout seul...

                          Sinon, tu peux toujours coder une fonction en C (une UDF) pour mysql !
                          • Partager sur Facebook
                          • Partager sur Twitter

                          SELECT avec tri par nom

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown