我有两张桌子:
data
id |email
_
1 |xxx@gmail.com
2 |yyy@gmial.com
3 |zzzgimail.com
errors
_
error |correct
@gmial.com|@gmail.com
gimail.com|@gmail.com
如何从data
中选择包含电子邮件错误的所有记录?感谢。
答案 0 :(得分:1)
假设错误总是在字符串的末尾:
declare @data table (
id int,
email varchar(100)
)
insert into @data
(id, email)
select 1, 'xxx@gmail.com' union all
select 2, 'yyy@gmial.com' 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
答案 1 :(得分: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。
答案 2 :(得分:0)
嗯,实际上你不能使用你提供的信息。
在SQL中,您需要维护一个“正确”域的表。有了它,你可以做一个简单的查询来找到不匹配。
您可以在SQL Server中使用某些“非”SQL功能来执行正则表达式检查,但是这种逻辑在SQL(IMO)中不会低于此类。
答案 3 :(得分:0)
select * from
(select 1 as id, 'xxx@gmail.com' as email union
select 2 as id, 'yyy@gmial.com' 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 + '%'
我认为......如果您在开始时没有使用通配符,但在之后的任何地方,它可以从索引中受益。如果您使用全文搜索,它也可能会受益。