T-SQL:在字符串中查找列匹配(LIKE但不同)

时间:2014-12-16 15:36:13

标签: tsql sql-server-2008-r2

服务器:SQL Server 2008 R2

我提前道歉,因为我不确定用语言表达问题的最好方法。我收到一串电子邮件地址,我需要查看在该字符串中是否已存在任何用户地址。显然不起作用的查询如下所示,但希望它有助于澄清我正在寻找的内容:     

SELECT f_emailaddress
FROM tb_users
WHERE f_emailaddress LIKE '%user1@domain.com,user2@domain.com%'

我希望SQL有一个“InString”运算符,可以检查“字符串内”的匹配项,但我今天的Google功能必须很弱。

非常感谢任何帮助。如果根本就没有办法,我将不得不深入挖掘并在代码隐藏中做一些工作来分割字符串中的每个项目并搜索每个项目。

提前致谢, Beems

5 个答案:

答案 0 :(得分:1)

首先需要将CSV列表拆分为临时表,然后将其用于INNER JOIN与现有表格,因为它将充当过滤器。

除非您在该表和列上创建了全文索引,否则不能使用CONTAINS,我怀疑是这种情况。

例如:

CREATE TABLE #EmailAddresses (Email NVARCHAR(500) NOT NULL);

INSERT INTO #EmailAddress (Email)
   SELECT split.Val
   FROM   dbo.Splitter(@IncomingListOfEmailAddresses);

SELECT usr.f_emailaddress
FROM tb_users usr
INNER JOIN #EmailAddresses tmp
        ON tmp.Email = usr.f_emailaddress;

请注意参考&#34; dbo.Splitter&#34;是您已经拥有或可能获得的任何字符串拆分器的占位符。请使用任何使用WHILE循环的拆分器。最好的选择是基于SQLCLR或基于XML的选项。基于XML的通常很快,但如果要拆分的字符串具有特殊的XML字符,例如&<",则会遇到编码问题。如果您想要一个快速简便的基于SQLCLR的分割器,您可以下载SQL#库的免费版本(我是其创建者,但此功能在免费版本中),其中包含String_SplitString_Split4k(当输入总是&lt; = 4000个字符时)。

答案 1 :(得分:1)

拆分输入字符串并使用IN clause

将CSV拆分为行使用此功能。

SELECT Ltrim(Rtrim(( Split.a.value('.', 'VARCHAR(100)') )))
FROM   (SELECT Cast ('<M>'
                     + Replace('user1@domain.com,user2@domain.com', ',', '</M><M>')
                     + '</M>' AS XML) AS Data) AS A
       CROSS APPLY Data.nodes ('/M') AS Split(a) 

现在在where子句中使用上述查询。

SELECT f_emailaddress
FROM   tb_users
WHERE  f_emailaddress IN(SELECT Ltrim(Rtrim(( Split.a.value('.', 'VARCHAR(100)') )))
                         FROM   (SELECT Cast ('<M>'
                                              + Replace('user1@domain.com,user2@domain.com', ',', '</M><M>')
                                              + '</M>' AS XML) AS Data) AS A
                                CROSS APPLY Data.nodes ('/M') AS Split(a)) 

或者使用可以使用Inner Join

SELECT f_emailaddress
FROM   tb_users A
       JOIN (SELECT Ltrim(Rtrim(( Split.a.value('.', 'VARCHAR(100)') )))
             FROM   (SELECT Cast ('<M>'
                                  + Replace('user1@domain.com,user2@domain.com', ',', '</M><M>')
                                  + '</M>' AS XML) AS Data) AS A
                    CROSS APPLY Data.nodes ('/M') AS Split(a)) B
         ON a.f_emailaddress = b.f_emailaddress 

答案 2 :(得分:0)

SQL具有CONTAINSIN功能。您可以使用其中任何一个来完成任务。点击以获取更多信息,请访问MSDN网站!希望这会有所帮助。

CONTAINS

CONTAINS会查看数据中的任何值是否包含您提供的整个字符串。类似于LIKE '%myValue%';

的演示文稿
SELECT f_emailaddress
FROM tb_users
WHERE CONTAINS (f_emailaddress, 'user1@domain.com');

IN

IN将返回所提供的逗号分隔列表中任何值的匹配项。然而,他们需要完全匹配。您无法提供部分条款。

SELECT f_emailaddress
FROM tb_users
WHERE f_emailaddress IN ('user1@domain.com','user2@domain.com')

至于将每个值拆分为单独的字符串,请查看找到的{0}的StackOverflow问题。这可能会指向正确的方向。

答案 3 :(得分:0)

您可以尝试这样(未经测试)。

在使用此功能之前,请确保您已在该表和列上创建了全文索引。

用AND替换你的逗号,然后

SELECT id,email
FROM t
where CONTAINS(email, 'user1@domain.com and user2@domain.com');

答案 4 :(得分:0)

--prepare temp table for testing
DECLARE @tb_users AS TABLE
    (f_emailaddress VARCHAR(100))
INSERT  INTO @tb_users
        ( f_emailaddress)
VALUES  ( 'user1@domain.com' ),
        ( 'user2@domain.com' ),
        ( 'user3@domain.com' ),
        ( 'user4@domain.com' )
--Your query
SELECT  f_emailaddress
FROM    @tb_users
WHERE   'user1@domain.com,user2@domain.com' LIKE '%' + f_emailaddress + '%'