【问题标题】:Finding a Specific Character and/or String SQL Server 2008查找特定字符和/或字符串 SQL Server 2008
【发布时间】:2015-02-15 07:39:36
【问题描述】:

我有两列包含电子邮件信息。 A 列,B 列。现在,在这些字段中,电子邮件应该是这样的:

 Column A                 Column B
 x@x.com; b@b.com         abc@x.com; xyz@x.com
 x@x.com;b@b.com          abc@x.com;xyz@x.com

但是,为了进行一些数据质量检查等,事实证明许多条目并未遵循这种格式。我正在尝试查找所有异常值,并且我已经确定了异常值以采用以下形式:

x@x.com and b@b.com
x@x.com, b@b.com (uses comma so it is incorrect)
x@x.com or b@b.com
x@x.com / b@b.com

可能还有其他错误的字符或单词导致格式不正确。但我希望这些例子能指出问题所在。

我正在尝试做的事情: 创建一个查询以查明所有格式不正确的实例,以便稍后可以找到和编辑问题点,但这是一个不同的主题:)

这是我到目前为止的一个查询:

SELECT     A_EMAIL, B_EMAIL, NAME, ID
FROM         NAMES

WHERE A_EMAIL LIKE ('and %') OR A_EMAIL LIKE ('or %') 
OR B_EMAIL LIKE ('and %') OR B LIKE ('or %')

这是使用 LIKE 并且 % 之间有一个空格。但是,这不会返回任何结果,而且我知道这样的结果确实存在。但我想建立一个逻辑,让我找回所有格式不正确的东西,而不是尝试使用 LIKE 'XYZ',因为即使我知道大部分问题,我仍然可能会错过一些。

但是,如果这样的事情通过 SQL 是不可能的。然后我仍然希望使用我当前的逻辑使用 LIKE ('XYZ %') 来代替它,即使不是最佳路线,也应该能够以某种方式帮助我实现目标。

【问题讨论】:

  • 如果可能的话,你应该把它标准化。它会节省你数小时的悲伤,试图找出像这样的问题。
  • 意思是,继续尝试并找到解决方案,它将给我所有的问题问题,而不是走 LIKE ('XYZ %') 类型的路线。理解并同意。但是,如果不可能,我将不得不求助于后一种路线。
  • 不确定您的最后一条评论是什么意思,但是...我的意思是将电子邮件拆分为一个子表,这样您的表中的单个交集就不会有多个值。然后你可以向应用程序添加一些验证来捕获它以防止将来发生这种事情。

标签: sql sql-server string sql-like


【解决方案1】:

试试这样的

Create Table #Emails (Email varchar(128))
Go

Insert into #Emails
Values 
  ('goodguy@greatdomain.com')
, ('another.great.email@somemailserver.somedaomain.com')
, (Null)
, ('a@b.c')
, ('a@b.c and x@y.z')
, ('x@x.com and b@b.com')
, ('x@x.com, b@b.com')
, ('x@x.com or b@b.com')
, ('x@x.com / b@b.com')
Go

Select 
  Email
, Case 
    When Email Is Not Null 
     And LTrim(RTrim(Email)) Like '%_@__%.__%' 
     And LTrim(RTrim(Email)) Not Like '% %' 
        Then 'Good' 
        Else 'Bad' 
  End Quality
From #Emails

原[坏]

不完美,但选择如下类似语句。好机会会让你占多数

NOT LIKE '%_@__%.__%

【讨论】:

  • 这会带回 NULL 或 1 个字母 @ 1 letter.com 的条目(奇怪的是,有几次这样的情况)。这仍然有帮助。但它并没有带回电子邮件或其他内容之间包含“AND”一词的主要问题。
【解决方案2】:

我建议您删除空格,然后查找非电子邮件之类的字符:

where replace(cola, '; ', ';') like '%[^a-zA-Z0-9@ ;.]%'

即该列包含无效字符。

然后,我鼓励您创建一个联结表,这样您就不会将电子邮件列表存储在以分号分隔的列中。

【讨论】:

    【解决方案3】:

    您的查询很好,您只是漏掉了一个%。 而不是这个

    WHERE A_EMAIL LIKE ('and %') OR A_EMAIL LIKE ('or %') 
    OR B_EMAIL LIKE ('and %') OR B LIKE ('or %')
    

    你应该使用这个

    WHERE A_EMAIL LIKE ('%and %') OR A_EMAIL LIKE ('%or %') 
    OR B_EMAIL LIKE ('%and %') OR B LIKE ('%or %')
    

    您的原始查询会查找以 'and ' 开头的值,而您对列值内任何位置出现 'and ' 的情况感兴趣。

    当然,这是解决您当前问题的一次性解决方案。 永久的解决方案是首先不要将多封电子邮件存储在同一列中。

    【讨论】:

    • 我很惊讶您接受了这个答案,因为它没有完全回答这个问题。例如,它不能正确地将 'x@x.com / b@b.com''x@x.com, b@b.com' 识别为坏的。
    • 我刚刚修复了原始查询的语法。当然,可能还有很多其他搜索条件,具体取决于数据中的真实垃圾。现在很清楚原始查询的问题所在,因此很容易添加更多子句 OR LIKE ('%/ %') OR LIKE ('%, %') 等等...
    【解决方案4】:

    我相信一个简单的 Not like 查询将足以满足您的要求,如下所示

    Select * From EmailTable Where Email NOT LIKE '%;%'
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-31
      • 1970-01-01
      • 2013-01-11
      • 1970-01-01
      • 2013-03-25
      相关资源
      最近更新 更多