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

Langage SQL Discussion :

Récupération entier a travers une chaine


Sujet :

Langage SQL

  1. #1
    Membre régulier
    Récupération entier a travers une chaine
    bonjour a tous

    J'ai besoin de mettre en œuvre une requête SQL qui me permet de récupérer l'entier qui est déjà encapsuler a travers une chaîne de caractère

    j'ai cette liste .

    AR 60310.V.EAB
    AR 100 -4-1
    FR 294 AR
    FR ISO 3506-1 ED
    fr 5200-25-6

    Besoin de sortie

    60310
    100
    294
    3506
    5200

    j'ai penser a substring replace mais malheureusement j'ai pas abouti a une résultat suffisante

    Qui peut m'aider SVP

    merci

  2. #2
    Rédacteur/Modérateur

    Bonjour,

    la moindre des choses aurait été de préciser le SGBDR utilisé !
    La seule chose absolue dans un monde comme le nôtre, c'est l'humour. » Albert Einstein

    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Tokyo, Rio, Sidney) et peut être quelques autres
    SGBD : Firebird 2.5, 3, SQLite
    générateurs Etats : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Ubuntu, Androïd

  3. #3
    Expert éminent sénior
    Et il faut préciser aussi la règle d'extraction : pourquoi extraire "52000" dans la chaine "fr 5200-25-6" et pas plutôt "25" et/ou "6" qui sont également des valeurs numériques

    Ce besoin est certainement du à une grosse erreur de modélisation : votre colonne source ne contient pas de données atomiques, ce qui vous contraint à une gymnastique complexe et couteuse pour extraire ces données.
    Voyez s'il est possible de modifier la table pour stocker ces valeurs atomiques plutôt que ces concaténations difficiles à utiliser

  4. #4
    Modérateur

    Si toutes les données sont du même format 2 caractères + espace + nombre + autre chose, vous pouvez essayer ça :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    SELECT CAST(SUBSTRING(la_colonne FROM 4) AS UNSIGNED)
    FROM la_table


    Ça fonctionne en tout cas avec le premier exemple de donnée que vous avez fourni :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    SELECT CAST(SUBSTRING('AR 60310.V.EAB' FROM 4) AS UNSIGNED)

    Résultat : 60310

    EDIT : Solution donnée pour MySQL et à adapter pour les autres SGBD.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  5. #5
    Rédacteur

    Citation Envoyé par CinePhil Voir le message
    Si toutes les données sont du même format 2 caractères + espace + nombre + autre chose, vous pouvez essayer ça :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    SELECT CAST(... AS UNSIGNED) ...
    N'oublie pas que UNSIGNED n'existe pas en SQL !!!!

    A +
    Cette signature n'a pas pu être affichée car elle comporte des erreurs.

  6. #6
    Modérateur

    Oui, je m'étais cru dans le forum MySQL. J'ai fait un Edit de mon message.

    En SQL Standard, ça peut fonctionner avec un CAST... AS INTEGER, non ?
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  7. #7
    Expert éminent sénior
    Citation Envoyé par CinePhil Voir le message
    Si toutes les données sont du même format 2 caractères + espace + nombre + autre chose, vous pouvez essayer ça :
    Oui mais non, la ligne 4 ne correspond pas :

    Citation Envoyé par NULL008 Voir le message
    J'ai cette liste :

    AR 60310.V.EAB
    AR 100 -4-1
    FR 294 AR
    FR ISO 3506-1 ED
    fr 5200-25-6

    Besoin de sortie

    60310
    100
    294
    3506
    5200
    Il faut donc une règle de gestion, peut être est-ce la 1ère occurrence de chaine constituée de chiffres, à confirmer

  8. #8
    Modérateur

    Arf !
    Alors je ne vois pas de solution simple. Toujours sous MySQL, voici une méthode possible :
    Utiliser ma technique en plusieurs étapes, si besoin en injectant le résultat de ce type de requêtes dans une nouvelle table :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT CAST(SUBSTRING(la_colonne FROM 4) AS UNSIGNED)
    FROM la_table
    WHERE CAST(SUBSTRING(la_colonne, 4, 1) AS UNSIGNED) BETWEEN 0 AND 9

    => Ne retournera pas la ligne FR ISO 3506-1 ED

    Adapter ensuite la requête aux lignes similaires restant à traiter :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT CAST(SUBSTRING(la_colonne FROM 8) AS UNSIGNED)
    FROM la_table
    WHERE CAST(SUBSTRING(la_colonne, 8, 1) AS UNSIGNED) BETWEEN 0 AND 9

    => Traitera la ligne FR ISO 3506-1 ED en retournant 3506

    Sinon, développer une procédure SQL qui va parcourir chaque caractère de la chaîne pour trouver la position du premier chiffre et extraire le nombre avec une requête similaire à ci-dessus.

    Ou bien encore traiter ça par un programme externe.

    Avec un autre SGBD que MySQL, on peut peut-être trouver la position du premier chiffre à l'aide d'une CTE mais je maîtrise mal cette technique alors je passe la main.
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  9. #9
    Rédacteur

    Une solution classique consiste à créer une fonction de nettoyage qui ne renvoit que les chiffres et transforme tous les autres caractères en espace, puis une autre fonction qui récupère le groupe de caractères numérique situé en position n dans la chaine résultante.

    Tout ceci étant contre performant par nature parce que contrevanant comme déjà dit aux principes fondamentaux des SGBDR à savoir l'atomicité des données (forme normale n°1)....

    A +
    Cette signature n'a pas pu être affichée car elle comporte des erreurs.

  10. #10
    Modérateur

    Bonjour,

    En effet, connaitre le SGBDR est indispensable pour une réponse adaptée, chacun ayant ses propres fonctions et subtilités pour traiter les chaines de caractères.

    Sous SQL Server, on peut simplement faire ceci, qui s'appuie sur la recherche de motif dans la chaine :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    SELECT 
    	SUBSTRING(
    			LaColonne
    		,	PATINDEX('%[0-9]%',LaColonne)
    		,	PATINDEX('%[0-9][^0-9]%', LaColonne) - PATINDEX('%[0-9]%',LaColonne) + 1
    	)
    FROM LaTable

  11. #11
    Membre expérimenté
    Si tu es sous SGBD ORACLE, la solution est dans les expressions régulières.

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    with tt as
     
    (
    select 'AR 60310.V.EAB' txt from dual union 
    select 'AR 100 -4-1' txt from dual union 
    select 'FR 294 AR' txt from dual union 
    select 'FR ISO 3506-1 ED' txt from dual union 
    select 'fr 5200-25-6'  txt from dual 
     
    )
     
    select txt,regexp_substr(txt,'\d+')  sortie from tt


    Resultat:

    TXT | SORTIE
    AR 100 -4-1 | 100
    AR 60310.V.EAB | 60310
    FR 294 AR |294
    FR ISO 3506-1 ED |3506
    fr 5200-25-6 |5200
    d'avoir Pensé à voter positivement pour ceux qui vous ont aidés et surtout à mettre si le cas.
    ça encourage.

###raw>template_hook.ano_emploi###