这个问题的不同之处在于,我们不是在寻找精确匹配,而是在另一个内部寻找一个值。考虑生产描述:

 "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()函数的更多信息。

INSTRING_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, ' ') )

有几个步骤发生:

  1. STRING_SPLIT()返回一个Product.Name中的单词表
  2. 子查询测试查看“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

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐