IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

Tri Alphanumérique Oracle 9i


Sujet :

SQL Oracle

  1. #1
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 20
    Par défaut Tri Alphanumérique Oracle 9i
    Bonjour je souhaite faire un tri alphanumérique sur une colonne d'une table

    Le résultat que j'attend est le suivant :

    1
    5
    5E8
    6
    10
    100
    101
    200E1
    Blabla
    Toto
    Zorro

    Donc on tri en ordre naturel sur une colonne alphanumérique.

    Pour l'instant j'utilise un NLS_SORT que j'ai mis à FRENCH_M mais les chiffres sont triés de cette façon

    1
    10
    100
    2
    20
    200

    Sur Oracle 9i le Regex est impossible car implémenté à la version 10, je pensé à un substr et un instr, mais je ne sais pas comment m'y prendre.

    Merci

  2. #2
    Membre éprouvé
    Inscrit en
    Septembre 2008
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 101
    Par défaut
    Bonjour,

    Ce que tu appel tri "naturel" ne l'est pas tant que cela :
    pourquoi l'ordre suivant 5, 5E8, 6, 51 est correct et pas 5, 6, 51, 5E8 ?

    Tu essayes de mélanger 2 règles de tri numérique et alphabétique.
    Le tri réalisé par Oracle est bien alphabétique, "ab" est bien avant "b" --> "10" est aussi avant "2"

    Pour arriver à ce que tu veux, tu peux essayer de formater ta chaine de caractères sur n positions avec LPAD (mais ca ne semble pas correspondre) ou calculer toi même un "rang" pour chaque chaine de caractere.

  3. #3
    Rédacteur

    Homme Profil pro
    Consultant / formateur Oracle et SQL Server
    Inscrit en
    Décembre 2002
    Messages
    3 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Consultant / formateur Oracle et SQL Server

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 461
    Par défaut
    Citation Envoyé par pazair16 Voir le message
    ...Donc on tri en ordre naturel ...
    C'est peut-être naturel dans votre esprit, mais je trouve votre exemple incompréhensible.
    D'une part, vous n'avez pas les mêmes valeurs en haut et en bas, et d'autre part, je ne vois pas quel sens ça a de mettre 5E8 entre 5 et 6.

    Oups désolé, je n'avais pas vu la réponse précédente !

  4. #4
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 20
    Par défaut
    Ce sont des noms de rue que je veux classer, donc (1,2,3,10 ect....) j'avais eu la solution pour le faire sous postgres (Merci punkoff)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT val, substring(val FROM '#"[0-9]*#"%' FOR '#')
    FROM tb1
    ORDER BY case 
    when substring(val FROM '#"[0-9]*#"%' FOR '#') > '' then substring(val FROM '#"[0-9]*#"%' FOR '#')::int
    else NULL end,
    val;
    Pour résumer j'aimerai avoir les chiffre avant les lettres, et faire en sorte que les lettres soient triées en ordre "Naturel". Vous comptez comme ça vous ? :1, 10, 100, 2, 22, 200

    Bref le problème est que je suis sur Oracle 9i donc les possibilités sont réduites, et je n'ai pas assez de recul sur le SQL de oracle pour pouvoir appréhender toutes ses possibilités.

    Merci

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 454
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 454
    Par défaut
    Votre tri est complètement personnalisé, vous aviez eu une solution personnalisée sous PostGreSQL, il suffit donc de coder votre propre solution personnalisée sous Oracle.

    Après cinq minutes de tests, ceci devrait faire l'affaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    With TMP as
    (
    select '1' as col from dual union all
    select '5'        from dual union all
    select '5E8'      from dual union all
    select '6'        from dual union all
    select '10'       from dual union all
    select '100'      from dual union all
    select '101'      from dual union all
    select '200E1'    from dual union all
    select 'Blabla'   from dual union all
    select 'Toto'     from dual union all
    select 'Zorro'    from dual union all
    select '2'        from dual union all
    select '20'       from dual union all
    select '200'      from dual
    )
      select col
        from TMP
    order by to_number(case col
                         when translate(col, '#' || translate(col, '#0123456789', '#'), '#')
                         then col
                         else substr(col, 1, instr(col, translate(col, '#0123456789', '#'))-1)
                       end) asc nulls last
           , col asc;
     
    COL
    -------
    1
    2
    5
    5E8
    6
    10
    20
    100
    101
    200
    200E1
    Blabla
    Toto
    Zorro

  6. #6
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 20
    Par défaut
    Les données que j'ai donné sont des données fictives, les vrais sont dans une table qui se trouve dans une colonne avec plus de 25000 lignes

    Je ne comprend pas une partie de la requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    WITH TMP AS
    (
    SELECT '1' AS col FROM dual union ALL
    SELECT '5'        FROM dual union ALL
    SELECT '5E8'      FROM dual union ALL
    SELECT '6'        FROM dual union ALL
    SELECT '10'       FROM dual union ALL
    SELECT '100'      FROM dual union ALL
    SELECT '101'      FROM dual union ALL
    SELECT '200E1'    FROM dual union ALL
    SELECT 'Blabla'   FROM dual union ALL
    SELECT 'Toto'     FROM dual union ALL
    SELECT 'Zorro'    FROM dual union ALL
    SELECT '2'        FROM dual union ALL
    SELECT '20'       FROM dual union ALL
    SELECT '200'      FROM dual
    )
    Vous comprendrez bien que je n'ai pas les valeur Toto et Zorro dans mes tables.

    il faudrais que je remplace cette partie par ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    WITH TMP AS 
    (
    Select Champ_a_trier as col FROM dual union ALL
    )
    Pouvez vous m'expliquer sa fonction ??

  7. #7
    Membre éprouvé
    Inscrit en
    Septembre 2008
    Messages
    101
    Détails du profil
    Informations forums :
    Inscription : Septembre 2008
    Messages : 101
    Par défaut
    Dans l'exemple de Waldar, la parti suivante de la requete sert à "simuler" une table de données
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    WITH TMP AS 
    (SELECT Champ_a_trier AS col FROM dual union ALL ...)
    Ce qui t'intéresse, c'est cette partie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT col
        FROM TMP
    ORDER BY to_number(case col
                         when translate(col, '#' || translate(col, '#0123456789', '#'), '#')
                         then col
                         else substr(col, 1, instr(col, translate(col, '#0123456789', '#'))-1)
                       end) ASC nulls last
           , col ASC;
    où TMP représente ta TABLE et COL représente la colonne à trier

    Pour plus d'explication sur le WITH, voir ici : http://www.dba-oracle.com/t_sql99_with_clause.htm

  8. #8
    Membre averti
    Homme Profil pro
    Inscrit en
    Mars 2011
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 20
    Par défaut
    Merci a tous pour vos réponse, cela m'a grandement aidé.

    J'ai ensuite rajouté des clauses dans le order by, pour ceux que ça interesse, je classe par une colonne en mettant les champs non vide en premier ce qui donne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    case when champs_a_trier ='' then null else champs_a_trier END
    Voila merci je passe en résolu.

  9. #9
    McM
    McM est déconnecté
    Expert confirmé

    Homme Profil pro
    Développeur Oracle
    Inscrit en
    Juillet 2003
    Messages
    4 580
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur Oracle

    Informations forums :
    Inscription : Juillet 2003
    Messages : 4 580
    Billets dans le blog
    4
    Par défaut
    Ce n'est pas bon.. un test ='' ou "= NULL" ne sera jamais vrai
    Donc pour moi ce code ne sert à rien
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    case when champs_a_trier ='' then NULL else champs_a_trier END
    Je n'ai pas compris ce que tu voulais faire exactement, mais il existe la clause NULLS FIRST/LAST dans le ORDERS BY

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT col
    FROM (SELECT NULL AS col FROM dual UNION ALL SELECT 1 FROM dual)
    ORDER BY col
    COL
    1
    <null>
     
    SELECT col
    FROM (SELECT NULL AS col FROM dual UNION ALL SELECT 1 FROM dual)
    ORDER BY col NULLS FIRST
    COL
    <null>
    1

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [V6] problème de tri alphanumérique
    Par briolins dans le forum Deski
    Réponses: 7
    Dernier message: 04/11/2009, 15h57
  2. Tri alphanumérique sql
    Par eddyrigotti dans le forum SQL
    Réponses: 3
    Dernier message: 22/10/2009, 10h20
  3. [Système] Tri alphanumérique en UTF-8
    Par nazoreen dans le forum Langage
    Réponses: 5
    Dernier message: 24/06/2007, 14h15
  4. Réponses: 1
    Dernier message: 22/06/2007, 12h48
  5. Réponses: 5
    Dernier message: 23/01/2006, 19h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo