在 SQL 服务器的 nvarchar 列中搜索电子邮件

Search for an email in an nvarchar column in SQL Server

我想在 SQL 服务器的 nvarchar 列中搜索特定的电子邮件(例如,fname@exmaple.com)。它应该像 -

一样简单
Select * from Discussion where Comments like '%fname@example.com%'

但是上述查询不包括一个案例。如果结果集包含评论,例如“来自电子邮件为 selfname@example.com 的用户的评论”。在这种情况下,上述查询将 return 包含 'fname@example.com' 和 'selfname@example.com'.

的记录

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

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

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

  1. lorem ipsum fname@exmaple.com
  2. fname@example.com lorem ipsum
  3. Lorem ipsum fname@exmaple.com dolor sit amet

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

  1. selfname@example.com dolor sit amet
  2. Lorem ipsum selfname@exmaple.com dolor sit amet

提前致谢。

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

  1. 电子邮件在中间

  2. 电子邮件在开头

  3. 邮件在最后

  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”等情况,它应该可以按照您描述的方式工作。

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

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

如果可以有其他分隔符——例如圆括号、句法等等——那么这就更麻烦了。一种方法是使用 translate():

将它们替换为空格
where concat(' ', translate(Comments, '(),:;', '     '), ' ') like '% fname@example.com %'

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

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

    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 table 中再做一个过滤器 喜欢

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

您可以复制并粘贴此查询并在我这边检查其工作情况,

我提出了以下查询。

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 (' ', '<', '>', '"', '''', ',', ';', '=', '(', ')', '*'))

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