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 :

"Normalisation" d'une chaine de données [11gR2]


Sujet :

SQL Oracle

  1. #1
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 115
    Points : 59
    Points
    59
    Par défaut "Normalisation" d'une chaine de données
    Bonjour,

    J'ai en entrée une table Oracle qui a la structure suivante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Champ_Id  Champ_Nb    Champ_Chaine
      u1           3        12.5;256.6;1.0
      u2           1        105.9
      u3           2        1.5
    Je souhaite "normaliser" les données de mon Champ_Chaine pour les mettre dans une table avec une ligne par valeur.
    Voici ce que j'attends en sortie (nouvelle table)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     Champ_Id   Champ_Nb   Champ_Num  Champ_Chaine
       u1            3          1       12.5
       u1            3          2       256.6
       u1            3          3       1.0
       u2            1          1       105.9
       u3            2          1       1.5
       u3            2          2       null
    Je pensais passer par une boucle de traitement mais je ne sais pas comment l'écrire.

    Les différentes valeurs de Champ_Chaine sont de longueur variable, je sais seulement qu'elles sont séparées par des ";".


    Pourriez-vous m'aider ?
    Un grand merci.
    MarieO

  2. #2
    McM
    McM est déconnecté
    Expert éminent

    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
    Points : 7 740
    Points
    7 740
    Billets dans le blog
    4
    Par défaut
    Bonjour,

    Premièrement, attention à ta nouvelle table : La colonne "Champ Nb" ne sera pas maintenable (si tu crées ou supprime une ligne, tu ne pourras pas mettre à jour les autres lignes)

    Ensuite pour ta procédure de traitement voici un algorithme (à toi de le mettre en format sql)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Boucle sur la table_Orig
     
    Si champ_chaine est vide alors on insère une ligne dans table_Dest
    sinon 
     var chaine = champ_chaine (avec un ; en fin de rajouté)
     tantque chaine est non vide
     alors on récupère le premier code, jusqu au ;
         on insère une ligne dans table_dest
         chaine = on supprime la partie à gauche du premier ; (inclus)
     fin tantque
    fin si
     
    Fin boucle table_Orig
    More Code : More Bugs. Less Code : Less Bugs
    Mon Blog PL/Sql : Fichier Zip / Image BMP / Lire sqliteDB / QRCode et Images PNG ou BMP

  3. #3
    Membre du Club
    Inscrit en
    Mai 2006
    Messages
    115
    Détails du profil
    Informations forums :
    Inscription : Mai 2006
    Messages : 115
    Points : 59
    Points
    59
    Par défaut
    Bonjour,

    Merci beaucoup pour cette réponse.
    Je n'avais pas pensé à ajouter un ";" en fin de chaine afin de simplifier le traitement.
    J'ai donc écrit une boucle qui travaille sur la recherche des ";" pour déterminer la longueur des chaines à insérer dans le champ Champ_chaine.

    Bonne journée,
    MarieO

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 763
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 763
    Points : 52 554
    Points
    52 554
    Billets dans le blog
    5
    Par défaut
    Inutile de faire une procédure ou d'ajouter un ; à la fin.... Une seule requête suffit !

    Démonstration :

    1) la table
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    CREATE TABLE T_CHAINES
    (champ_id          CHAR(16) PRIMARY KEY,
     champ_nb          INT,
     Champ_chaine      VARCHAR(256));
    2) les données
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSERT INTO T_CHAINES VALUES
    ('u1',      3,        '12.5;256.6;1.0'),
    ('u2',      1,        '105.9'),
    ('u3',      2,        '1.5');
    3) la solution
    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 
    T_LEN AS (SELECT MAX(LENGTH(Champ_chaine)) AS L
              FROM T_CHAINES),
    T_NUM AS (SELECT 1 AS N
              UNION ALL
              SELECT N + 1
              FROM   T_NUM
              WHERE  N < (SELECT L FROM T_LEN)),
    T_CAR AS (SELECT champ_id, N AS N
              FROM   T_CHAINES AS C
                     JOIN T_NUM AS I ON SUBSTRING(Champ_chaine, N, 1) = ';'
              UNION ALL
              SELECT champ_id, LENGTH(Champ_chaine)+1
              FROM   T_CHAINES),
    T_LIM AS (SELECT champ_id, COALESCE(LAG(N) OVER(PARTITION BY champ_id ORDER BY N), 0) AS DEBUT, N AS FIN
              FROM   T_CAR)   
    SELECT C.champ_id, SUBSTRING(Champ_chaine, DEBUT + 1, FIN-DEBUT-1) AS chaine
    FROM   T_LIM AS L
           JOIN T_CHAINES AS C
                On L.champ_id = C.champ_id
    4) le résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    champ_id         chaine
    ---------------- ------------
    u1               12.5
    u1               256.6
    u1               1.0
    u2               105.9
    u3               1.5
    Et pour apprendre ou approfondir le SQL :
    Nom : Couverture SQL Synthex 4e ed - 500.jpg
Affichages : 186
Taille : 77,8 Ko

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 936
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 936
    Points : 4 356
    Points
    4 356
    Par défaut
    Erratum, correction de syntaxe pour ORACLE:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ...
    T_NUM(n) AS (SELECT 1 AS N FROM DUAL
              UNION ALL
              SELECT N + 1
              FROM   T_NUM tn
              WHERE  tn.N < (SELECT L FROM T_LEN)),
    ...
    + facultatif à la fin:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    order by C.champ_id, l.fin

    si l'ordre peut avoir une importance…


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

Discussions similaires

  1. Tripler les bits d'une chaine de données
    Par Kazeshine dans le forum Débuter
    Réponses: 8
    Dernier message: 19/03/2014, 17h49
  2. normalisation d'une chaine de caractères
    Par Bricolab dans le forum MATLAB
    Réponses: 6
    Dernier message: 29/02/2012, 14h19
  3. extraction d'une donnée d'une chaine de caractères.
    Par LESOLEIL dans le forum Langage
    Réponses: 10
    Dernier message: 20/04/2006, 12h00
  4. copie de string donne une chaine vide
    Par zmatz dans le forum SL & STL
    Réponses: 5
    Dernier message: 15/10/2005, 15h31
  5. recherche d'une chaine de caractère dans une données text
    Par jdeheul dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 17/06/2004, 16h35

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