这个问题的不同之处在于,我们不是在寻找精确匹配,而是在另一个内部寻找一个值。考虑生产描述:
"Mountain Bike with lightweight frame yet rugged enough to tackle the toughest trails."
我们可以在SQL中使用什么来测试描述是否包含“frame”这个词?
使用LIKE和模式匹配
您可以使用LIKE运算符来匹配模式。您可以使用通配符来匹配列中的单词和字符。
要查找所有包含“frame”的产品名称,我们可以使用:
select ProductID, ProductNumber, Name ProductName
from Production.Product
where Name like '%frame%'
检查模式。百分号(%)指示模式匹配零个或多个字符。在英语中,这种模式说,“寻找'frame'不要担心它之前或之后的内容。”
CHARINDEX()查找单词的位置
CHARINDEX()是一个TSLQ函数,它返回一个字符表达式在另一个字符表达式中的起始位置。我们可以使用它来帮助我们确定我们的SQL列是否包含搜索到的文本。
继续我们的例子,如果我们正在寻找“Frame”,我们可以使用这个查询:
select ProductID, ProductNumber, Name ProductName
from Production.Product
where CHARINDEX('frame', name) > 0
这是因为如果在列名中找到“frame”,CHARINDEX()返回大于0的值。如果未找到该值,则返回零。
PATINDEX()查找模式的位置
PATINDEX() TSQL函数非常相似于CHARINDEX();,但是它可以采用模式进行匹配。这就是LIKE进行匹配的方式。他们使用相同的模式匹配思想。
要在其Product.Name中查找“frame”,请使用此查询以及PATINDEX():
select ProductID, ProductNumber, Name ProductName
from Production.Product
where PATINDEX('%frame%', name) > 0
要了解有关PATINDEX查看我的文章SQL PATINDEX()函数的更多信息。
IN与STRING_SPLIT()的有趣用法
您可能认为您可以使用该IN子句来查找Frame,并且在某种程度上您是部分正确的。但有一件事是肯定的,这个查询是行不通的!
select ProductID, ProductNumber, Name ProductName
from Production.Product
where name in ('frame')
问题是过滤器在与“frame”比较之前首先将名称分解为单词。幸运的是,有一个SQL函数可以解决这个问题。
为了解决这个难题,我们将使用STRING_SPLIT()。与其他输出单个值的函数不同,STRING_SPLIT ()返回一个表。
这个例子你可以看到我们在哪里将字符串“Hail to the Victors”分成四个单独的单词。
知道我们返回了一个表,让我们编写一个子查询并使用IN运算符。我们将测试其STRING_SPLIT()结果中是否包含“frame”:
select ProductID, ProductNumber, Name ProductName
from Production.Product
where 'frame' in (select value from STRING_SPLIT(name, ' ') )
有几个步骤发生:
- STRING_SPLIT()返回一个Product.Name中的单词表
- 子查询测试查看“frame”是否在此表中,如果是,则IN比较返回TRUE。
在SQL中使用CONTAINS()进行全文搜索
我们将讨论的最终解决方案是CONTAINS()。如果一个单词包含在另一个短语中,例如我们的列Product.Name,则返回 true 。
它似乎是最明显的选择,直到您意识到它需要一些前期工作。
由于CONTAINS依赖于SQL的全文功能,因此您需要确保在DBMS中安装了这些功能。此外,为了在列上使用,该列需要一个FULLTEXT索引。
以下是设置索引的方法:
create fulltext catalog ft as default
create fulltext index on Production.Product(name) key index ak_product_name with stoplist=system
一旦完成,查询就很简单了:
select ProductID, ProductNumber, Name ProductName
from Production.Product
where CONTAINS(name, 'frame')
这种技术具有潜力,尤其是当您需要搜索大量全文(例如水平沉积)时。如果这是您想要做的事情,请查看Microsoft的全文搜索文章。
结论
在列出的所有技术中,我最可能使用的是LIKE。当涉及到查询时,它很容易设置,并且它的模式匹配功能很方便。
话虽如此,不要低估其他技术。以为我会一直在查询中使用它们,这些功能很方便,我不时使用它们。
本文最初发布于Contains in SQL - Essential SQL
https://www.codeproject.com/Articles/5326745/Contains-in-SQL