2010-08-03 8 views

Répondre

1

Il existe plusieurs solutions possibles en fonction exactement ce dont vous avez besoin: utilisation pourrait créer table auxiliaire pour stocker mot-clé pour chaque enregistrement

  1. Utilisez le tableau auxiliaire pour stocker des mots-clés pour chaque enregistrement ou enregistrer et champ. Par exemple. table_helper (id int clé primaire, record_id int, mot clé varchar), record_id - lien vers la table source. Remplissez cette table dans le déclencheur pour table1, table2. La recherche de lignes communes est une simple intersection de table_helper avec elle-même. Vous pouvez créer une aide pour table1 et table2 ou utiliser des tables séparées.
  2. Utilisez les index de texte intégral.
2

Vous pouvez essayer les fonctions SOUNDEX ou DIFFERENCE pour vous aider à faire correspondre les littéraux de chaîne.

Exemple:

select difference('peter.green', 'Green, Peter') 

2 rendements, grâce à quoi:

L'entier renvoyé est le nombre de caractères dans les valeurs SOUNDEX que sont les mêmes. La plage de valeurs de retour de 0 à 4: 0 indique faible ou aucune similitude, et 4 indique une forte similitude ou les mêmes valeurs.

Voir les rubriques SOUNDEX et DIFFERENCE sur MSDN.

Mise à jour:

Soundex & différence peut ne pas fonctionner quand sont considérés comme l'ordre des mots, mais si vous avez des capacités d'indexation en texte intégral installé, vous n'avez pas besoin de créer un index pour utiliser le mot capacités de rupture et d'analyse du moteur de texte intégral. En supposant que vous utilisez SQL Server 2008, la fonction suivante vous renvoie une liste de termes normalisés:

SELECT * FROM sys.dm_fts_parser('"Peter Green"', 1033, 0, 0) 

à travers lequel vous pouvez CROSS APPLY au reste de votre requête.

Voir le sys.dm_fts_parser rubrique & Section K. Utilisation de Apply dans le domaine FROM pour plus d'informations.

Exemple: (SQL Server Enterprise 2008 avec texte intégral du moteur activé)

if not OBJECT_ID('Names1', 'Table') is null drop table names1 
if not OBJECT_ID('Names2', 'Table') is null drop table names2 

create table Names1 
(
    id int identity(0, 1), 
    name nvarchar(128) 
) 
insert into Names1 (name) values ('Green, Peter') 
insert into Names1 (name) values ('Smith, Peter') 
insert into Names1 (name) values ('Aadland, Beverly') 
insert into Names1 (name) values ('Aalda, Mariann') 
insert into Names1 (name) values ('Aaliyah') 
insert into Names1 (name) values ('Aames, Angela') 
insert into Names1 (name) values ('Aames, Willie') 
insert into Names1 (name) values ('Aaron, Caroline') 
insert into Names1 (name) values ('Aaron, Quinton') 
insert into Names1 (name) values ('Aaron, Victor') 
insert into Names1 (name) values ('Abbay, Peter') 
insert into Names1 (name) values ('Abbott, Dorothy') 
insert into Names1 (name) values ('Abbott, Bruce') 
insert into Names1 (name) values ('Abbott, Bud') 
insert into Names1 (name) values ('Abbott, Philip') 
insert into Names1 (name) values ('Abdoo, Rose') 
insert into Names1 (name) values ('Abdul, Paula') 
insert into Names1 (name) values ('Abel, Jake') 
insert into Names1 (name) values ('Abel, Walter') 
insert into Names1 (name) values ('Abeles, Edward') 
insert into Names1 (name) values ('Abell, Tim') 
insert into Names1 (name) values ('Aber, Chuck') 

create table Names2 
(
    id int identity(200, 1), 
    name nvarchar(128) 
) 
insert into Names2 (name) values (LOWER('Peter.Green')) 
insert into Names2 (name) values (LOWER('Peter.Smith')) 
insert into names2 (name) values (LOWER('Beverly.Aadland')) 
insert into names2 (name) values (LOWER('Mariann.Aalda')) 
insert into names2 (name) values (LOWER('Aaliyah')) 
insert into names2 (name) values (LOWER('Angela.Aames')) 
insert into names2 (name) values (LOWER('Willie.Aames')) 
insert into names2 (name) values (LOWER('Caroline.Aaron')) 
insert into names2 (name) values (LOWER('Quinton.Aaron')) 
insert into names2 (name) values (LOWER('Victor.Aaron')) 
insert into names2 (name) values (LOWER('Peter.Abbay')) 
insert into names2 (name) values (LOWER('Dorothy.Abbott')) 
insert into names2 (name) values (LOWER('Bruce.Abbott')) 
insert into names2 (name) values (LOWER('Bud.Abbott')) 
insert into names2 (name) values (LOWER('Philip.Abbott')) 
insert into names2 (name) values (LOWER('Rose.Abdoo')) 
insert into names2 (name) values (LOWER('Paula.Abdul')) 
insert into names2 (name) values (LOWER('Jake.Abel')) 
insert into names2 (name) values (LOWER('Walter.Abel')) 
insert into names2 (name) values (LOWER('Edward.Abeles')) 
insert into names2 (name) values (LOWER('Tim.Abell')) 
insert into names2 (name) values (LOWER('Chuck.Aber')); 

with ftsNamesFirst (id, term) as 
(
    select id, terms.display_term 
     from names1 cross apply sys.dm_fts_parser('"' + name + '"', 1033, 0, 0) terms 
), ftsNamesSecond (id, term) as 
(
select id, terms.display_term 
     from names2 cross apply sys.dm_fts_parser('"' + name + '"', 1033, 0, 0) terms 
) 
select * from 
(
    select 
    ROW_NUMBER() over (partition by nfirst.id order by sum(DIFFERENCE(ftsNamesFirst.term, ftsNamesSecond.term)) desc) ranking, 
    sum(DIFFERENCE(ftsNamesFirst.term, ftsNamesSecond.term)) Confidence, 
    nFirst.id Names1ID, 
    nFirst.name Names1Name, 
    nSecond.id Names2ID, 
    nSecond.name Names2Name 
    from 
    ftsNamesFirst cross join ftsNamesSecond 
    left outer join names1 nFirst on nFirst.id = ftsNamesFirst.id 
    left outer join names2 nSecond on nSecond.id = ftsNamesSecond.id 
    where DIFFERENCE(ftsNamesFirst.term, ftsNamesSecond.term) = 4 
    group by 
     nFirst.id, nFirst.name, nSecond.id, nSecond.name 
) MatchedNames 
where ranking = 1 

Sorties:

Où prendre les matches avec confiance plus haute priorité (tous les autres sont filtrés à l'aide d'un requête de classement fenêtrée).

Confidence Names1ID Names1Name Names2ID Names2Name 
8 0 Green, Peter 200 peter.green 
8 1 Smith, Peter 201 peter.smith 
8 2 Aadland, Beverly 202 beverly.aadland 
8 3 Aalda, Mariann 203 mariann.aalda 
4 4 Aaliyah 204 aaliyah 
8 5 Aames, Angela 205 angela.aames 
8 6 Aames, Willie 206 willie.aames 

Ce n'est pas parfait, mais c'est un bon point de départ d'où il peut être modifié pour donner une plus grande probabilité de succès.

Questions connexes