2010-10-26 4 views
3

Je ces deux tableaux:Sélectionnez les enregistrements avec une sous-chaîne d'une autre table

data  
id |email  
_ 
1 |[email protected]  
2 |[email protected]  
3 |zzzgimail.com 

errors  
_  
error |correct  
@gmial.com|@gmail.com  
gimail.com|@gmail.com  

Comment puis-je choisir de data tous les enregistrements avec une erreur de courrier électronique? Merci.

+0

Nous aimons les questions SQL! –

+0

yey! J'espère que cela sera promu bientôt ... http://area51.stackexchange.com/proposals/4260/databases?referrer=diRC8jcl2i-5LIh8JGLLjA2 –

Répondre

1
SELECT d.id, d.email 
FROM data d 
    INNER JOIN errors e ON d.email LIKE '%' + e.error 

ferait, en faisant cependant LIKE avec un caractère générique au début de la valeur étant égalés sur empêchera un indice d'être utilisé afin que vous puissiez voir une mauvaise performance.

Une approche optimale consisterait à définir une colonne calculée sur la table de données, c'est-à-dire l'INVERSE du champ email et à l'indexer. Transformerait la requête ci-dessus dans une condition LIKE avec le caractère générique à la fin comme ceci:

SELECT d.id, d.email 
FROM data d 
    INNER JOIN errors e ON d.emailreversed LIKE REVERSE(e.error) + '%' 

Dans ce cas, la performance serait mieux car elle permettrait d'utiliser un index. J'ai écrit un blog complet sur cette approche a while ago here.

+0

merci adathedev, cela fonctionne mieux. –

0

Eh bien, en réalité, vous ne pouvez pas avec les informations que vous avez fournies.

En SQL, vous devez maintenir une table de domaines "corrects". Avec cela, vous pouvez faire une requête simple pour trouver des non-correspondances.

Vous pouvez utiliser une fonctionnalité "non" SQL dans SQL Server pour effectuer une vérification d'expression régulière, mais ce type de logique ne figure pas ci-dessous dans SQL (IMO).

1

En supposant que l'erreur est toujours à la fin de la chaîne:

declare @data table (
    id int, 
    email varchar(100) 
) 

insert into @data 
    (id, email) 
    select 1, '[email protected]' union all 
    select 2, '[email protected]' union all 
    select 3, 'zzzgimail.com' 

declare @errors table (
    error varchar(100), 
    correct varchar(100) 
) 

insert into @errors 
    (error, correct) 
    select '@gmial.com', '@gmail.com' union all 
    select 'gimail.com', '@gmail.com' 

select d.id, 
     d.email, 
     isnull(replace(d.email, e.error, e.correct), d.email) as CorrectedEmail 
    from @data d 
     left join @errors e 
      on right(d.email, LEN(e.error)) = e.error 
+0

désolé Joe, j'ai dû changer ma réponse acceptée, mais je vous ai donné un vote up, j'espère que cela ne vous dérange pas –

+1

@eiefai: Pas de problème du tout. –

0
select * from 
(select 1 as id, '[email protected]' as email union 
select 2 as id, '[email protected]' as email union 
select 3 as id, 'zzzgimail.com' as email) data join 

(select '@gmial.com' as error, '@gmail.com' as correct union 
select 'gimail.com' as error, '@gmail.com' as correct) errors 

on data.email like '%' + error + '%' 

Je pense ... que si vous n'utilisiez pas un caractère générique au début mais n'importe où après, il pourrait bénéficier d'un index. Si vous avez utilisé une recherche en texte intégral, cela pourrait également en bénéficier.

Questions connexes