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 :

Comparer des chaînes de caractères dans deux tables différentes


Sujet :

SQL Oracle

  1. #1
    Membre régulier Avatar de ninatity
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2010
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Octobre 2010
    Messages : 64
    Points : 74
    Points
    74
    Par défaut Comparer des chaînes de caractères dans deux tables différentes
    Bonjour à tous,

    J'ai vraiment besoin d'aide dans une requête que je dois faire.
    J'ai 2 tables différentes contenant l'une, des informations fiscales provenant de la Direction des Impôts et l'autre des informations fiscales données par des clients. Mon soucis c'est que je dois mettre à jour les données fiscales des clients de ma base et la colonne que je dois employer pour les jointures (NOM) n'a pas les mêmes données exactes.

    Exemple :
    NOM_IMPOTS NOM_CLIENT
    MARTIN DUBOIS & CIE STE MARTIN ET DUBOIS
    MARC LEVY-STRAUSS MARC ANTHONY LEVY-STRAUSS

    J'ai déjà éssayer LIKE, INSTR mais sans résultat. Pourriez-vous me guider? Merci d'avance.

  2. #2
    Membre averti
    Homme Profil pro
    Ingénieur en études décisionnelles
    Inscrit en
    Février 2013
    Messages
    134
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur en études décisionnelles

    Informations forums :
    Inscription : Février 2013
    Messages : 134
    Points : 351
    Points
    351
    Par défaut
    Bonjour,

    Est-ce vraiment la seule clé dont tu disposes ? Tu n'as pas de numéro de siret sur lequel tu pourrais joindre ?


    Sinon, ce que je ferais, c'est créer deux nouvelles colonnes NOM_IMPOTS_TMP et NOM_CLIENT_TMP. J'alimenterais respectivement ces deux colonnes à partir de NOM_IMPOTS et NOM_CLIENT afin d'avoir un espace de travail.
    Ensuite, j'essaierais de trouver les règles qui permettent de faire le remplacement.
    Transformer les '&' en 'ET'... Enfin, tout ce que tu peux trouver, jusqu'à ce que tu aies deux colonnes identiques. Et ensuite joindre sur ces colonnes.

    Mais vu tes données j'ai du mal à voir comment une unique requête te permettra d'avoir ce que tu souhaites. Déjà, si tu joins avec un like '%MARTIN%' par exemple (beurk), tu risques de perdre ton lien 1,1, ce qui n'est pas ce que tu veux j'imagine...

  3. #3
    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
    Impossible à faire en automatique avec une fiabilité de 100%
    Tu peux te créer une fonction de similarité afin de voir les rapprochements possibles, mais tu auras forcément une validation d'un utilisateur

  4. #4
    Membre régulier Avatar de ninatity
    Femme Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2010
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 37
    Localisation : Madagascar

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Octobre 2010
    Messages : 64
    Points : 74
    Points
    74
    Par défaut
    Est-ce vraiment la seule clé dont tu disposes ? Tu n'as pas de numéro de siret sur lequel tu pourrais joindre ?
    Je n'ai que les deux colonnes provenant de la Direction des impôts (Nom et NIF). Ils ne veulent pas nous donner plus d'informations . Oui j'ai déjà fait le LIKE '%MARTIN%', cela sort pleines de lignes et je ne veux pas me tromper.
    Impossible à faire en automatique avec une fiabilité de 100%
    Bref merci pour vos conseils, je vais chercher quelques astuces et je vous tiendrai au courant.

  5. #5
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    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 453
    Points : 18 386
    Points
    18 386
    Par défaut
    Quel est le volume de données que vous devez recouper ?

    Oracle implémente nativement une version légèrement boguée de la distance de Jaro-Winkler dont les résultats avaient été probants sur un besoin similaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    with cte_clients (lid, nom_impots, nom_client) as
    (
    select 1, 'MARTIN DUBOIS & CIE', 'STE MARTIN ET DUBOIS'      from dual union all
    select 2, 'MARC LEVY-STRAUSS'  , 'MARC ANTHONY LEVY-STRAUSS' from dual
    )
      select lid
           , round(100 * utl_match.jaro_winkler(nom_impots, nom_client), 3) as jws
        from cte_clients
    order by lid asc;
     
           LID        JWS
    ---------- ----------
             1     71,404
             2     86,541
    Le score calculé est un pourcentage de correspondance.

    Un des défauts de cet algorithme est sont coût CPU : vous aller devoir calculer les scores de beaucoup de correspondances : même 2000 vs 2000, ça fait 4.000.000 de calculs.

    Ce que nous avions fait avec les collègues à l'époque, était de rechercher d'abord les correspondances exactes, puis les correspondances like, puis les correspondances via la distance de Jaro-Winkler afin d'en faire le moins possible.

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 868
    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 868
    Points : 53 022
    Points
    53 022
    Billets dans le blog
    6
    Par défaut
    Bonjour

    Utilisez l'algorithme de rapprochement que j'ai écrit :
    http://sqlpro.developpez.com/cours/s...ns-motifs/#LVI
    Il est très rapide...
    Il donne même d'excellent résultat pour la police à la recherche des terroriste dont les noms sont phonétisés par rapport par exemple à l'arabe !

    Si vous écrivez la fonction en PL/SQL, renvoyez moi le code afin que je le publie....
    A +

  7. #7
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    La voila (bref j'ajouterais des commentaires un de ces jours)
    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
     
    CREATE OR REPLACE Function F_INFERENCE_BASIQUE (
      StrSource          In Varchar2,
      StrCible           In Varchar2
    ) Return Pls_Integer Is
      --
      Score    Pls_Integer := Null;
      --
      Function Compare (
        StrSource     In Varchar2,
        StrCible      In varchar2
      ) Return Pls_Integer Is
        Ch     Char;
        Cpt    Pls_Integer := 0;
        j      Pls_Integer := 1;
      Begin
        For i In 1..Length(Compare.StrSource)
        Loop
          Ch := SubStr(Compare.StrSource, i, 1);
          If InStr(Compare.StrCible, Ch, j) > 0
          Then
            Cpt := Cpt + 1;
            j := InStr(Compare.StrCible, Ch, j) + 1;
          End If;
        End Loop;
        Return Cpt;
      End;
      --
    Begin
      If StrSource Is Not Null And StrCible Is Not Null
      Then
        Score := Compare(StrSource, StrCible); -- premièr passage
        If Score > 0 
        Then
          Score := Greatest(Score, Compare(StrCible, StrSource));  -- deuxiéme passage
        End If;  
      End If;    
      --
      Return Score;
    End;
    Et le jeux de test
    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 
     
    SQL> 
    SQL> With Data As (
      2    Select 'Chemise16' as a, 'Vrt' as b, 'Vert' as c from dual union all
      3    Select 'Chemise17', 'Blenc', 'Blanc' from dual union all
      4    Select 'Pantalon1', 'Rouge', 'Rouge' from dual union all
      5    Select 'Pantalon11', 'Gris souris', 'Gris' from dual union all
      6    Select 'Pantalon14', 'Rouge brique', 'Rouge' from dual union all
      7    Select 'Pantalon6', 'Gris bleu', 'Bleu' from dual union all
      8    Select 'Pantalon6', 'Gris bleu', 'Gris' from dual union all
      9    Select 'Pantalon7', 'Vert', 'Vert' from dual union all
     10    Select 'Pull13', 'bleue', 'Bleu' from dual union all
     11    Select 'Pull15', 'Marron', 'Marron' from dual union all
     12    Select 'Pull4', 'Jaune paille', 'Jaune' from dual union all
     13    Select 'Pull9', 'blanc', 'Blanc' from dual union all
     14    Select 'Robe10', 'Blanche', 'Blanc' from dual union all
     15    Select 'Robe12', 'rose', 'Rose' from dual union all
     16    Select 'Robe2', 'Vert d''eau', 'Vert' from dual union all
     17    Select 'Robe3', 'Viol.', 'Violet' from dual union all
     18    Select 'Robe5', 'Verte', 'Vert' from dual union all
     19    Select 'Robe8', 'Rouge', 'Rouge' from dual
     20  )
     21  Select a, b, c,
     22         F_INFERENCE_BASIQUE(b,c) FintB,
     23         F_INFERENCE_BASIQUE(Upper(b),Upper(c)) Fintb_Upp,
     24         utl_match.jaro_winkler(b,c)jar
     25    from Data
     26  /
    A          B            C           FINTB  FINTB_UPP        JAR
    ---------- ------------ ------ ---------- ---------- ----------
    Chemise16  Vrt          Vert            3          3      0,925
    Chemise17  Blenc        Blanc           4          4 0,89333333
    Pantalon1  Rouge        Rouge           5          5          1
    Pantalon11 Gris souris  Gris            4          4 0,87272727
    Pantalon14 Rouge brique Rouge           5          5 0,88333333
    Pantalon6  Gris bleu    Bleu            3          4          0
    Pantalon6  Gris bleu    Gris            4          4 0,88888888
    Pantalon7  Vert         Vert            4          4          1
    Pull13     bleue        Bleu            3          4 0,78333333
    Pull15     Marron       Marron          6          6          1
    Pull4      Jaune paille Jaune           5          5 0,88333333
    Pull9      blanc        Blanc           4          5 0,86666666
    Robe10     Blanche      Blanc           5          5 0,94285714
    Robe12     rose         Rose            3          4 0,83333333
    Robe2      Vert d'eau   Vert            4          4       0,88
    Robe3      Viol.        Violet          4          4 0,89333333
    Robe5      Verte        Vert            4          4       0,96
    Robe8      Rouge        Rouge           5          5          1
    18 rows selected
     
    SQL>
    /Edit Ajouté jaro pour comparaison.

  8. #8
    Membre chevronné Avatar de Garuda
    Homme Profil pro
    Chef de projet / Urbaniste SI
    Inscrit en
    Juin 2007
    Messages
    1 285
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Vaucluse (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Chef de projet / Urbaniste SI
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2007
    Messages : 1 285
    Points : 2 071
    Points
    2 071
    Par défaut
    @mnitu : j'ai essayé la fonction mais je suis en 10g et le "continue" (dans la fonction compare) n'existe pas dans cette version. Sauf incompréhension, il ne sert à rien. Me trompes-je ?

  9. #9
    Expert éminent sénior Avatar de mnitu
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2007
    Messages
    5 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2007
    Messages : 5 611
    Points : 11 252
    Points
    11 252
    Par défaut
    Citation Envoyé par Garuda Voir le message
    ... Me trompes-je ?
    Non, c'est superfétatoire! Merci pour ta remarque j'ai modifié le code.

  10. #10
    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
    @Sqlpro, j'ai trouvé une erreur dans l'énoncé de la "Différence de Hamming"

    C'est tout simplement le nombre de symboles différents d'une chaîne à l'autre... Il suffit de lire séquentiellement les deux chaînes en comparant chaque lettre à la position n dans les deux mots. Si la lettre est identique on compte 1.
    C'est : Si la lettre est différente on compte 1.

    Il faudrait aussi rajouter : Malus de 1 si les chaines sont de tailles différentes, car je ne comprenais pas le 4 pour "Vrt" et "Vert" avant de lire le code.

Discussions similaires

  1. Comparer des chaînes de caractères
    Par aurelie689 dans le forum Débuter avec Java
    Réponses: 1
    Dernier message: 02/05/2009, 13h22
  2. Réponses: 2
    Dernier message: 30/04/2009, 12h46
  3. [16F876] Ecrire des chaînes de caractères dans un tableau
    Par aminousse dans le forum Autres architectures
    Réponses: 0
    Dernier message: 01/03/2008, 01h08
  4. Changer des chaînes de caractères dans un fichier
    Par troumad dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 10/11/2006, 08h45

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