【问题标题】:Search for an email in an nvarchar column in SQL Server在 SQL Server 的 nvarchar 列中搜索电子邮件
【发布时间】:2020-12-23 11:15:14
【问题描述】:

我希望在 SQL Server 的 nvarchar 列中搜索特定电子邮件(例如 fname@exmaple.com)。它应该很简单 -

Select * from Discussion where Comments like '%fname@example.com%'

但是,上述查询并未涵盖一种情况。如果结果集包含诸如“来自电子邮件 selfname@example.com 的用户的评论”之类的评论。在这种情况下,上述查询将返回包含“fname@example.com”和“selfname@example.com”的两条记录。

我正在寻找一个 sql 查询,其中电子邮件地址完全匹配,其余文本可以是任何内容。

我正在尝试在多个表中搜索电子邮件。我们在其中搜索电子邮件的列可以是 xml,nvarchar(max) 用于 cmets,nvarchar(50) 用于仅电子邮件。我们需要对记录集执行另一项工作。

结果集: 如果我正在搜索“fname@example.com”,结果集应包含以下内容:

  1. lorem ipsum fname@exmaple.com
  2. fname@example.com lorem ipsum
  3. Lo​​rem ipsum fname@exmaple.com dolor sit amet

结果集不应包含以下内容:

  1. selfname@example.com dolor sit amet
  2. Lo​​rem ipsum selfname@exmaple.com dolor sit amet

提前致谢。

【问题讨论】:

  • 邮件地址不能加空格吗? like '% fname@example.com %'
  • 您能否详细说明您在结果中究竟需要什么?
  • 是上面的免费类型,还是会一直是'Comment from a user with email {Email Address}'的格式,或者你能不能有类似''用户使用电子邮件地址{Email地址}发表评论'“?有吗?电子邮件地址后面的文本?但是,理想情况下,电子邮件似乎应该是一个不同的列,您应该修改您的设计。
  • 顺便说一句,如果您正在检查 nvarchar,那么它也可以与 nvarchar 进行比较:N'%fname@example.com%'
  • @Dhrumilshah - 我添加了一些结果集应该是什么样子的示例。谢谢。

标签: sql sql-server text-parsing


【解决方案1】:

在电子邮件之后或之前检查非字母数字字符(如此处所述:LIKE Transact-SQL)并区分所有可能的情况可能会很有用:

  1. 电子邮件在中间

  2. 电子邮件在开头

  3. 电子邮件在末尾​​p>

  4. 列仅包含电子邮件

    SELECT * 
      FROM Discussion 
     WHERE Comments LIKE '%[^a-z0-9]fname@example.com[^a-z0-9]%' --CASE 1
        OR Comments LIKE 'fname@example.com[^a-z0-9]%'           --CASE 2
        OR Comments LIKE '%[^a-z0-9]fname@example.com'           --CASE 3
        OR Comments = 'fname@example.com'                        --CASE 4
    

此外,通过这种方式,您可以覆盖您可能想要检测的“Lorem ipsum:fname@exmaple.com”之类的情况,并且它应该适用于您描述的广告。

【讨论】:

    【解决方案2】:

    首先,我们需要找到文本中包含的电子邮件地址,为此,我们需要识别“@”,为此,我们需要编写如下查询

        SELECT Id,Comments as Text,        
                    CASE
                        WHEN CHARINDEX('@',Comments) = 0 THEN NULL
                        ELSE SUBSTRING(Comments,beginningOfEmail,endOfEmail-beginningOfEmail)
                    END email
             INTO #Temp1 FROM Discussion 
            CROSS APPLY (SELECT CHARINDEX(' ',Comments + ' ',CHARINDEX('@',Comments ))) AS A(endOfEmail)
            CROSS APPLY (SELECT DATALENGTH(Comments )/2 - CHARINDEX(' ',REVERSE(' ' + Comments),CHARINDEX('@',REVERSE(' ' + Comments ))) + 2) AS B(beginningOfEmail)
     -- stored data in Temp table , you can use alternative 
    
    SELECT id,email  FROM #Temp1 
    DROP table #Temp1
    

    输出

    id  email
    1   fname@exmaple.com
    2   fname@example.com
    3   hname@example.com
    4   fname@exmaple.com
    5   fname@example1.com
    6   selfname@example.com
    

    然后我们需要在 #Temp 表中再做一个过滤器 喜欢

    SELECT id,email  FROM #Temp1 
    where LEFT(email, CHARINDEX('@', email + '@') -1) like 'fname'
    

    SELECT id,email  FROM #Temp1 
        where LEFT(email, CHARINDEX('@', email + '@') -1) = 'fname'
    

    输出

    id  email
    1   fname@exmaple.com
    2   fname@example.com
    4   fname@exmaple.com
    5   fname@example1.com
    

    您可以复制并粘贴此查询并从我这里检查它的工作情况,

    【讨论】:

      【解决方案3】:

      如果您可以假设电子邮件的开头、结尾或被空格包围,那么您可以使用填充模式和带有空格的comments

      where concat(' ', Comments, ' ') like '% fname@example.com %'
      

      如果可以有其他分隔符——例如括号、语法等等——那么这就比较麻烦了。一种方法是使用translate() 将这些替换为空格:

      where concat(' ', translate(Comments, '(),:;', '     '), ' ') like '% fname@example.com %'
      

      不幸的是,. 是您正在寻找的模式的一部分,因此也很难包含它。

      【讨论】:

        【解决方案4】:

        我想出了以下查询。

        declare @searchText nvarchar(50) = 'fname@example.com'
        
        select * 
        from Discussion 
        where
            Comments = @searchText
            or (
                CHARINDEX(@searchText, Comments) > 0
                and SUBSTRING(Comments, CHARINDEX(@searchText, Comments) - 1, 1) in (' ', '<', '>', '"', '''', ',', ';', '=', '(', ')', '*') 
                and SUBSTRING(Comments, CHARINDEX(@searchText, Comments) + LEN(@searchText), 1) in (' ', '<', '>', '"', '''', ',', ';', '=', '(', ')', '*'))
        

        我正在寻找完全匹配或以其他方式检查前后字符以评估匹配是否符合条件。

        【讨论】:

          猜你喜欢
          • 2015-01-04
          • 1970-01-01
          • 2018-05-22
          • 1970-01-01
          • 1970-01-01
          • 2014-07-08
          • 2023-04-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多