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 :

Recherche varchar identiques à un caractère près


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4
    Par défaut Recherche varchar identiques à un caractère près
    Bonjour à tous,

    Sur une base Oracle 11GR2, je souhaite faire un select sur une colonne en varchar qui me retourne toutes les éléments identiques à un caractère près.
    J'essaie d’approfondir la piste en utilisant les regexp mais je n'ai pas abouti

    ex de résultats :

    SELECT NOM FROM matable ...

    'MICKAEL'
    'MICHAEL'
    'ARRIVAGE'
    'ARRIMAGE'

    Si quelqu'un a déjà fait cela ?
    Merci d'avance

  2. #2
    Membre Expert Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Par défaut
    Voulez vous ce type de résultat ou un autre ?

    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
    SQL> with t as ( select 'michael' c1, 'mickael' c2 from dual
      2              union all
      3              select 'michael'   , 'mickaela'   from dual
      4              union all
      5              select 'michael'   , 'mitchell'   from dual
      6              union all
      7              select 'michael'   , 'mickey'     from dual
      8              union all
                select 'arrivage'  , 'arrimage'   from dual )
      9   10  select c1
     11       , c2
     12      , replace(translate(c1,c2,lpad(' ',length(c2)) ),' ') diff
     13      , length(replace(translate(c1,c2,lpad(' ',length(c2)) ),' ')) tdiff
     14  from t
     15  /
     
    C1       C2       DIFF                                  TDIFF
    -------- -------- -------------------------------- ----------
    michael  mickael  h                                         1
    michael  mickaela h                                         1
    michael  mitchell a                                         1
    michael  mickey   hal                                       3
    arrivage arrimage v                                         1

  3. #3
    Membre Expert

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Par défaut
    Bonjour,

    La Distance de Levenshtein devrait faire l'affaire.

    Implémentez la fonction en PLSQL et utilisez là dans une requête de ce type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT T1.NOM 
    FROM matable T1
    INNER JOIN matable T2 
    ON LEVENSHTEIN(T1.NOM, T2.NOM) = 1
    AND T1.ID <> T2.ID

  4. #4
    Membre éclairé Avatar de LBO72
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Bonjour,
    A part le faire par du PlSql, je ne vois pas.
    Cdlt,
    LBO 72.

  5. #5
    Membre chevronné
    Avatar de Bibeleuh
    Homme Profil pro
    Développeur
    Inscrit en
    Septembre 2010
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 209
    Par défaut
    Sinon c'est pas la peine d'implémenter une fonction car le package UTL_MATCH contient déjà de telles fonctions :

    Exemple : la fonction EDIT_DISTANCE(VAR1,VAR2) qui te retourne la distance (le nombre de changements à faire pour que les 2 chaines soient égales)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SELECT UTL_MATCH.EDIT_DISTANCE('MICKAEL', 'MICHAEL')
    AS DISTANCE
    FROM DUAL;

  6. #6
    Membre Expert Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Par défaut
    tout dépend ce que l'on veut faire (je ne connaissait pas utl_match, au passage, merci )

    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
    with t as ( select 'michael' c1, 'mickael' c2 from dual
                union all
                select 'michael'   , 'mickaela'   from dual
                union all
                select 'michael'   , 'mitchell'   from dual
                union all
                select 'michael'   , 'mickey'     from dual
                union all
                select 'oracle'    , 'orkale'     from dual
                union all                      
                select 'oracle'    , 'creola'     from dual
                union all                      
                select 'oooooo'    , 'creola'     from dual
                union all                      
                select 'arrivage'  , 'arrimage'   from dual )        
    select c1
         , c2
         , replace(translate(c1
                            ,c2
                            ,lpad(' '
                                 ,length(c2)) )
                  ,' ')||' - '||replace(translate(c2
                                                 ,c1
                                                 ,lpad(' '
                                                      ,length(c1)) )
                                       ,' ') diff_let
         , abs(length(c1)-length(c2)) diff_len
         , (nvl(length(replace(translate(c1,c2,lpad(' ',length(c2)) ),' ')),0)
           +nvl(length(replace(translate(c2,c1,lpad(' ',length(c1)) ),' ')),0))/2 tdiff
         , nvl((nvl(length(replace(translate(c1,c2,lpad(' ',length(c2)) ),' ')),0)
               +nvl(length(replace(translate(c2,c1,lpad(' ',length(c1)) ),' ')),0))/2
              +abs(length(c1)-length(c2)),0) tdiff_l
         , UTL_MATCH.EDIT_DISTANCE(c1,c2) dist
    from t
    /
    Qui a pour résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    C1       C2       DIFF_LET          DIFF_LEN      TDIFF    TDIFF_L       DIST
    -------- -------- --------------- ---------- ---------- ---------- ----------
    michael  mickael  h - k                    0          1          1          1
    michael  mickaela h - k                    1          1          2          2
    michael  mitchell a - t                    1          1          2          3
    michael  mickey   hal - ky                 1        2.5        3.5          3
    oracle   orkale   c - k                    0          1          1          2
    oracle   creola    -                       0          0          0          4
    oooooo   creola    - crela                 0        2.5        2.5          5
    arrivage arrimage v - m                    0          1          1          1
    en clair, veut-on garder les anagrammes (oracle et creola), veut-on garder les mots qui ont les mêmes lettres à une près quelle que soit leur longueurs (michael et mitchell) ...

  7. #7
    Membre éclairé Avatar de LBO72
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    406
    Détails du profil
    Informations personnelles :
    Âge : 56
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 406
    Par défaut
    Respects monsieur vmolines :-) je ne connaissais absolument pas ce package.
    Merci pour ce super site dans lequel on apprend tous les jours

    Merci bibeleuh pour l'info sur le package, par contre je ne comprends pas il me retourne ce résultat pour le test ci-dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT UTL_MATCH.EDIT_DISTANCE('MICKAEL', 'LMICHAE')
    AS DISTANCE
    DISTANCE
    ----------
                3
    FROM DUAL;

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4
    Par défaut
    ce qui m'interesse c'est vraiment le dist = 1, je ne connaissais pas UTL_MATCH.EDIT_DISTANCE et je vais donc m'en servir.

    Merci beaucoup à tous et en particulier Bibeleuh.

  9. #9
    Membre chevronné
    Avatar de Bibeleuh
    Homme Profil pro
    Développeur
    Inscrit en
    Septembre 2010
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 209
    Par défaut
    Citation Envoyé par LBO72 Voir le message
    Merci bibeleuh pour l'info sur le package, par contre je ne comprends pas il me retourne ce résultat pour le test ci-dessous :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT UTL_MATCH.EDIT_DISTANCE('MICKAEL', 'LMICHAE')
    AS DISTANCE
    DISTANCE
    ----------
                3
    FROM DUAL;

    Pour passer de LMICHAE à MICKAEL :

    Etape 1 : LMICHAE
    Etape 2 : MICHAEL
    Etape 3 : MICKAEL

    Donc t'as bien une distance de 3 entre les deux, car 3 permutations étapes à faire

  10. #10
    Membre Expert
    Inscrit en
    Août 2009
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Août 2009
    Messages : 1 073
    Par défaut
    Citation Envoyé par Bibeleuh Voir le message
    Donc t'as bien une distance de 3 entre les deux, car 3 permutations à faire
    Permutation est impropre ici, mais ça correspond à 1 suppression, 1 ajout, et une substitution .

  11. #11
    Membre chevronné
    Avatar de Bibeleuh
    Homme Profil pro
    Développeur
    Inscrit en
    Septembre 2010
    Messages
    209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2010
    Messages : 209
    Par défaut
    Citation Envoyé par Rei Ichido Voir le message
    Permutation est impropre ici, mais ça correspond à 1 suppression, 1 ajout, et une substitution .
    Moi qui voulais utiliser des mots savants c'est raté ^^

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

Discussions similaires

  1. [XL-2007] recherche de chaîne de caractères identiques
    Par monk83 dans le forum Excel
    Réponses: 2
    Dernier message: 14/01/2012, 12h51
  2. recherche de chaine de caractéres
    Par donmamio dans le forum Langage
    Réponses: 6
    Dernier message: 04/05/2006, 07h22
  3. Rechercher une chaîne de caractère dans une série de fichier
    Par Edoxituz dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 28/02/2006, 12h51
  4. Réponses: 11
    Dernier message: 01/12/2004, 19h09
  5. Réponses: 3
    Dernier message: 09/05/2002, 01h39

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