代码之家  ›  专栏  ›  技术社区  ›  Eduardo Rascon

从另一个表中选择具有子字符串的记录

  •  3
  • Eduardo Rascon  · 技术社区  · 14 年前

    我有两张桌子:

    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 所有有电子邮件错误的记录?谢谢。

    4 回复  |  直到 14 年前
        1
  •  1
  •   AdaTheDev    14 年前
    SELECT d.id, d.email
    FROM data d
        INNER JOIN errors e ON d.email LIKE '%' + e.error
    

    这样做,但是在匹配值的开头使用通配符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
  •  1
  •   Joe Stefanelli    14 年前

    假设错误总是在字符串的末尾:

    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
    
        3
  •  0
  •   Dustin Laine    14 年前

    好吧,事实上你不能用你提供的信息。

    在SQL中,您需要维护一个“正确”域的表。有了它,您可以做一个简单的查询来查找不匹配项。

    您可以在SQL Server中使用一些“非”SQL功能来执行正则表达式检查,但是这种逻辑在SQL(IMO)中不在下面。

        4
  •  0
  •   Zachary Scott    14 年前
    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 + '%' 
    

    我想。。。如果您在开始时没有使用通配符,但在之后的任何地方都使用通配符,那么它可以从索引中受益。如果使用全文搜索,它也会受益。