2010-10-26 3 views
3

У меня есть эти две таблицы:Выбрать записи с подстроки из другой таблицы

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

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

Как я могу выбрать из data всех записей с ошибкой по электронной почте? Благодарю.

+0

Нам нравятся вопросы SQL! –

+0

yey! Я надеюсь, что это будет продвигаться в ближайшее время ... http://area51.stackexchange.com/proposals/4260/databases?referrer=diRC8jcl2i-5LIh8JGLLjA2 –

ответ

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

сделать бы это, однако делает LIKE с групповым символом в начале значения, совпадающим по помешают индекс от использования, чтобы вы могли видеть плохую производительность.

Оптимальным подходом было бы определение вычисленного столбца в таблице данных, то есть REVERSE поля электронной почты и индексация его. Это превратило бы выше запрос в LIKE состоянии с групповым символом в конце, как так:

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

В этом случае производительность будет лучше, так как это позволило бы индекс будет использоваться.

Я написал полную запись на этом подходе a while ago here.

+0

спасибо ададэдеву, это работает лучше. –

0

Ну, на самом деле вы не можете с информацией, которую вы предоставили.

В SQL вам нужно будет поддерживать таблицу «правильных» доменов. С этим вы можете сделать простой запрос, чтобы найти несоответствия.

Вы можете использовать некоторые «не» SQL-функции SQL Server для выполнения проверки регулярных выражений, однако такая логика ниже в SQL (IMO).

1

Предполагая, что ошибка всегда в конце строки:

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

Извините, Джо, мне пришлось изменить принятый ответ, но я дал вам предварительный голос, надеюсь, что вы не возражаете –

+1

@eiefai: Никаких проблем. –

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 + '%' 

Я думаю ... что если вы не использовали подстановочный знак в начале и нигде после этого, он мог бы воспользоваться индексом. Если вы использовали полнотекстовый поиск, это тоже может пригодиться.

Смежные вопросы