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 :

substr + replace dans un select


Sujet :

SQL Oracle

  1. #1
    Membre régulier
    Inscrit en
    Juin 2010
    Messages
    358
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 358
    Points : 77
    Points
    77
    Par défaut substr + replace dans un select
    Bonjour,

    Je cherche désespérément à faire apparaître un substr + un replace dans une même colonne lors d'un select.

    Je voudrais afficher le volume présent dans une colonne à un emplacement dont la longueur est un peu aléatoire : j'ai donc utilisé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    substr (matable.VOLUME, 19, 7),
    pour être large mais je peux dans ce cas déborder sur les informations suivantes, séparée par un -.

    J'ai donc pensé à remplacer le - par un espace :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    replace (matableVOLUME, '-', ''
    mais je ne parviens pas à lier les 2 pour que tout s'affiche dans une seule et même colonne et non pas sur 2 comme ci-dessous:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select 
    substr (matable.VOLUME, 19, 7),
    replace (matableVOLUME, '-', '')
    from matable
    Quelqu'un aurait-il une idée ?

    Merci.
    Microsoft SQL Server Management Studio v17.9.1

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 197
    Points : 12 772
    Points
    12 772
    Par défaut
    Bonjour,
    Peut être en faisant un replace(substr(...)), bref comme avec n'importe quel langage ?

    Tatayo.

  3. #3
    Membre régulier
    Inscrit en
    Juin 2010
    Messages
    358
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 358
    Points : 77
    Points
    77
    Par défaut
    C'est ce que j'ai tenté de faire au départ avec une requête de ce style :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    select 
    replace (replace (substr (matable.VOLUME, 19, 7), '-', ''))
    from matable
    Mais j'obtiens l'erreur suivante :"ORA-00938: nombre d'arguments insuffisant pour la fonction"

    Aussi avais-je pensé que je n'utilisais pas la bonne fonction alors qu'il s'agit peut-être d'une mauvaise syntaxe ?
    Microsoft SQL Server Management Studio v17.9.1

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 197
    Points : 12 772
    Points
    12 772
    Par défaut
    Il y a surtout un problème de paramètres.
    Si j'enlève le premier REPLACE:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    select 
    replace (substr (matable.VOLUME, 19, 7), '-', '')
    from matable
    On voit donc qu'il manque des paramètres pour l'autre REPLACE. Que doit-il remplacer, et par quoi ? C'est précisément ce qu'il manque. Et ces paramètres doivent se retrouver entre les deux parenthèses fermantes dans ta requête.

    Tatayo.

  5. #5
    Membre régulier
    Inscrit en
    Juin 2010
    Messages
    358
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 358
    Points : 77
    Points
    77
    Par défaut
    Le 2e replace doit remplacer un - pour du vide ('')

    Mais je n'arrive pas à les inclure de manière concluante dans la requête:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    replace (replace (substr (matable.VOLUME, 19, 7), substr (matable.VOLUME, '-', '')))
    Mais j'obtiens la même erreur.
    Microsoft SQL Server Management Studio v17.9.1

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 197
    Points : 12 772
    Points
    12 772
    Par défaut
    Si le deuxième replace remplace un tiret par du vide, que remplace le premier ?
    Je ne vois pas l'utilité ici d'utiliser 2 remplace.
    Si je comprends bien le besoin, la requête telle que je l'ai écrite fait le job.

    Tatayo.

  7. #7
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Essayez aussi de décrire votre besoin réel plutôt qu’interprété, car il y a de bonne chance qu'on puisse faire différemment.

  8. #8
    Membre régulier
    Inscrit en
    Juin 2010
    Messages
    358
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 358
    Points : 77
    Points
    77
    Par défaut
    Je vais effectivement utiliser un exemple plus concret.
    Voici comment se présentent les cellules dont j'essaye de tirer le volume de clients:

    Volumes Clients: 10167 - Véhicules: 10189
    Volumes Clients: 29559 - Véhicules: 29885
    Volumes Clients: 1637 - Véhicules: 1638
    Volumes Clients: 17513 - Véhicules: 17689
    Volumes Clients: 172004 - Véhicules: 173657

    Comme vous pouvez le constater, le volume débute toujours à la même place (19) mais le - qui le sépare des véhicules n'est pas fixe et fluctue en fonction du nombre de véhicules.

    Comment donc faire pour ne faire apparaître que le volume client dans une colonne de mon select ?
    Microsoft SQL Server Management Studio v17.9.1

  9. #9
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Ah vous voyez c'est tout de suite plus simple :
    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
    with cte_matable (id, col) as
    (
    select 1, 'Volumes Clients: 10167 - Véhicules: 10189'   from dual union all
    select 2, 'Volumes Clients: 29559 - Véhicules: 29885'   from dual union all
    select 3, 'Volumes Clients: 1637 - Véhicules: 1638'     from dual union all
    select 4, 'Volumes Clients: 17513 - Véhicules: 17689'   from dual union all
    select 5, 'Volumes Clients: 172004 - Véhicules: 173657' from dual
    )
    select id, col
         , substr(col, 18, instr(col, '-') - instr(col, ':') - 3) as vol_clients
         , substr(col, instr(col, ':', 1, 2) + 2)                 as vol_vehicules
      from cte_matable;
     
     ID COL                                         VOL_CLIENTS  VOL_VEHICULES
     -- ------------------------------------------- ------------ -------------
      1 Volumes Clients: 10167 - Véhicules: 10189   10167        10189        
      2 Volumes Clients: 29559 - Véhicules: 29885   29559        29885        
      3 Volumes Clients: 1637 - Véhicules: 1638     1637         1638         
      4 Volumes Clients: 17513 - Véhicules: 17689   17513        17689        
      5 Volumes Clients: 172004 - Véhicules: 173657 172004       173657
    Ou vous pouvez même utiliser une solution plus moderne qui utilise les expressions régulières - attention c'est plus consommateur en terme de CPU :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select id, col
         , to_number(regexp_substr(col, '(\d)+', 1, 1)) as vol_clients
         , to_number(regexp_substr(col, '(\d)+', 1, 2)) as vol_vehicules
      from cte_matable;

  10. #10
    Membre régulier
    Inscrit en
    Juin 2010
    Messages
    358
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 358
    Points : 77
    Points
    77
    Par défaut
    Pas évident à comprendre mais ça fonctionne très bien.

    Merci beaucoup !
    Microsoft SQL Server Management Studio v17.9.1

  11. #11
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    Ce n'est pas si compliqué de ça, il faut comprendre les deux fonctions substr et instr ainsi que leur différents paramètres.

    substr (comme sub-string) est une fonctionne qui permet d'extraire une chaîne à partir d'une autre.
    Elle prend en premier paramètre la chaîne de départ, en deuxième paramètre le caractère de départ et en dernier paramètre (facultatif) la longueur à extraire.

    Si j'écris select substr('ABCDEF', 3, 2) from dual je sors deux caractères à partir du troisième dans "ABCDEF" soit "CD".
    Lorsque le dernier paramètre n'est pas renseigné, on extrait jusqu'à la fin de la chaîne. Ainsi select substr('ABCDEF', 4) from dual donnera la chaîne "DEF".

    instr (comme in-string) est une fonction qui retrouve la position d'une chaîne dans une autre chaîne.
    Elle prend en premier paramètre la chaîne de départ, en deuxième paramètre la chaîne recherchée, en troisième paramètre (facultatif) la position de départ de la recherche et en quatrième paramètre (facultatif) la n-ième occurrence de la chaîne.

    Ainsi, select instr('ABCDEF', 'B') from dual donnera 2.
    select instr('ABABAB', 'AB') from dual donnera 1.
    select instr('ABABAB', 'AB', 1, 3) from dual donnera 5.
    select instr('ABABAB', 'AB', 2, 1) from dual donnera 3.

    Pour votre problème, concernant les clients, vous connaissez votre chaîne de départ, et le paramètre de départ. Ce qu'il vous manque c'est la longueur à extraire.
    Hors ça tombe bien, la longueur à extraire c'est la différence entre les positions du caractère "-" et du premier caractère ":", plus ou moins 3 espaces.
    C'est simplement ce qu'on retrouve ici : substr(col, 18, instr(col, '-') - instr(col, ':') - 3).

    Essayez de pratiquer un peu car ce sont des fonctions très utiles et massivement utilisées.

  12. #12
    Membre régulier
    Inscrit en
    Juin 2010
    Messages
    358
    Détails du profil
    Informations forums :
    Inscription : Juin 2010
    Messages : 358
    Points : 77
    Points
    77
    Par défaut
    Merci beaucoup pour cette explication très pédagogique: c'est maintenant plus clair.
    Microsoft SQL Server Management Studio v17.9.1

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

Discussions similaires

  1. [2008R2] Faire un Replace avec un Regex dans un select
    Par Sql2008 dans le forum Développement
    Réponses: 1
    Dernier message: 29/07/2013, 16h47
  2. [interbase][SQL] concatener 2 champs dans le select
    Par Harry dans le forum Bases de données
    Réponses: 10
    Dernier message: 09/03/2006, 06h45
  3. Joindre une valeur arbitraire dans un SELECT
    Par Tuxxy dans le forum Requêtes
    Réponses: 3
    Dernier message: 20/01/2004, 17h04
  4. Réponses: 3
    Dernier message: 23/09/2003, 09h12
  5. [Sybase] Select dans une select loop en C
    Par Claudio dans le forum Sybase
    Réponses: 2
    Dernier message: 29/04/2003, 18h06

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