SQL SELECT WHERE字段包含单词

Mar*_*o M 489 sql select

我需要一个select会返回如下结果:

SELECT * FROM MyTable WHERE Column1 CONTAINS 'word1 word2 word3'
Run Code Online (Sandbox Code Playgroud)

我需要所有结果,即这包括带有'word2 word3 word1'或'word1 word3 word2'的字符串或三者的任何其他组合.

所有单词都需要在结果中.

mvp*_*mvp 740

相当慢,但工作方法包括任何单词:

SELECT * FROM mytable
WHERE column1 LIKE '%word1%'
   OR column1 LIKE '%word2%'
   OR column1 LIKE '%word3%'
Run Code Online (Sandbox Code Playgroud)

如果您需要出现所有单词,请使用:

SELECT * FROM mytable
WHERE column1 LIKE '%word1%'
  AND column1 LIKE '%word2%'
  AND column1 LIKE '%word3%'
Run Code Online (Sandbox Code Playgroud)

如果你想要更快的东西,你需要查看全文搜索,这对每种数据库类型都是非常具体的.

  • @PreetSangha当您从外卡开始搜索LIKE时编制索引?请告诉我怎么样! (12认同)
  • + 1我同意它的速度较慢但可以通过良好的索引来缓解 (3认同)
  • 这种方法的另一个缺点是:'%word%'也会找到'words','crosswordpuzzle'和'sword'(仅作为示例).我必须做一个column1 LIKE'word'或者column1 LIKE'word%'或者column1 LIKE'%word'或者column1 LIKE'word'来找到确切的单词匹配 - 对于没有单词的条目它仍然会失败刚用空格分隔. (3认同)
  • @AquaAlex:如果文本包含“word3 word2 word1”,您的语句将失败。 (2认同)

Sam*_*Sam 70

请注意,如果您用于LIKE确定字符串是否是另一个字符串的子字符串,则必须转义搜索字符串中的模式匹配字符.

如果您的SQL方言支持CHARINDEX,则使用它会更容易:

SELECT * FROM MyTable
WHERE CHARINDEX('word1', Column1) > 0
  AND CHARINDEX('word2', Column1) > 0
  AND CHARINDEX('word3', Column1) > 0
Run Code Online (Sandbox Code Playgroud)

此外,请记住,这和接受的答案中的方法仅涵盖子字符串匹配而不是字匹配.因此,例如,字符串'word1word2word3'仍然匹配.

  • @ 23W MS SQL中没有InStr (5认同)
  • 在Microsoft SQL服务器和引擎中,我们应该使用`InStr()`而不是`CHARINDEX` (4认同)
  • @ShaneBlake而不是将“%”添加到变量中,只需将其添加到搜索中“%”+var+“%”是的,这有点 ty[ing 并且相当难看,但可能比更改变量的值更好。 (2认同)

Edu*_*omo 18

功能

 CREATE FUNCTION [dbo].[fnSplit] ( @sep CHAR(1), @str VARCHAR(512) )
 RETURNS TABLE AS
 RETURN (
           WITH Pieces(pn, start, stop) AS (
           SELECT 1, 1, CHARINDEX(@sep, @str)
           UNION ALL
           SELECT pn + 1, stop + 1, CHARINDEX(@sep, @str, stop + 1)
           FROM Pieces
           WHERE stop > 0
      )

      SELECT
           pn AS Id,
           SUBSTRING(@str, start, CASE WHEN stop > 0 THEN stop - start ELSE 512 END) AS Data
      FROM
           Pieces
 )
Run Code Online (Sandbox Code Playgroud)

询问

 DECLARE @FilterTable TABLE (Data VARCHAR(512))

 INSERT INTO @FilterTable (Data)
 SELECT DISTINCT S.Data
 FROM fnSplit(' ', 'word1 word2 word3') S -- Contains words

 SELECT DISTINCT
      T.*
 FROM
      MyTable T
      INNER JOIN @FilterTable F1 ON T.Column1 LIKE '%' + F1.Data + '%'
      LEFT JOIN @FilterTable F2 ON T.Column1 NOT LIKE '%' + F2.Data + '%'
 WHERE
      F2.Data IS NULL
Run Code Online (Sandbox Code Playgroud)

  • 好极了!主席先生,如何开始学习这一功能?什么是碎片?你能告诉我关于这行的伪代码吗?SUBSTRING(@str,开始,停止> 0然后停止的情况-开始ELSE 512 END)AS数据 (2认同)
  • 这个举动太不可思议了,我真的很嫉妒:( _______________________________________________________________________________________ INNER JOIN (@FilterTable F1 ON T.Column1 LIKE '%' + F1.Data + '%' LEFT JOIN (@FilterTable F2 ON T.Column1 NOT LIKE '%' + F2.数据 + '%' (2认同)

mes*_*-up 12

而不是SELECT * FROM MyTable WHERE Column1 CONTAINS 'word1 word2 word3',在这些词之间添加和:

SELECT * FROM MyTable WHERE Column1 CONTAINS 'word1 And word2 And word3'
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅此处 https://msdn.microsoft.com/en-us/library/ms187787.aspx

UPDATE

要选择短语,请使用双引号,如:

SELECT * FROM MyTable WHERE Column1 CONTAINS '"Phrase one" And word2 And "Phrase Two"'
Run Code Online (Sandbox Code Playgroud)

ps在使用contains关键字之前,您必须首先在表上启用全文搜索.有关详细信息,请参阅此处 https://docs.microsoft.com/en-us/sql/relational-databases/search/get-started-with-full-text-search


Jon*_*ell 8

SELECT * FROM MyTable WHERE 
Column1 LIKE '%word1%'
AND Column1 LIKE '%word2%'
AND Column1 LIKE  '%word3%'
Run Code Online (Sandbox Code Playgroud)

更改ORAND基于编辑问题.


mir*_*sif 5

如果您使用的是Oracle数据库,则可以使用包含查询来实现此目的.包含查询比查询更快.

如果你需要所有的话

SELECT * FROM MyTable WHERE CONTAINS(Column1,'word1 and word2 and word3', 1) > 0
Run Code Online (Sandbox Code Playgroud)

如果你需要任何一个词

SELECT * FROM MyTable WHERE CONTAINS(Column1,'word1 or word2 or word3', 1) > 0
Run Code Online (Sandbox Code Playgroud)

包含列上CONTEXT类型的需要索引.

CREATE INDEX SEARCH_IDX ON MyTable(Column) INDEXTYPE IS CTXSYS.CONTEXT
Run Code Online (Sandbox Code Playgroud)

  • @downvoters 感谢评论告诉答案有什么问题。同样的查询每天在我们的企业解决方案中运行超过 1000 次,没有任何问题:) (2认同)
  • OP没有指定正在使用哪个数据库,并且每个人都假设这是Sql Server。但是,由于您在响应中指定了Oracle,所以我不理解拒绝投票的人。 (2认同)

小智 5

如果你只是想找到一个匹配。

SELECT * FROM MyTable WHERE INSTR('word1 word2 word3',Column1)<>0
Run Code Online (Sandbox Code Playgroud)

SQL 服务器:

CHARINDEX(Column1, 'word1 word2 word3', 1)<>0
Run Code Online (Sandbox Code Playgroud)

获得精确匹配。示例(';a;ab;ac;',';b;')不会得到匹配。

SELECT * FROM MyTable WHERE INSTR(';word1;word2;word3;',';'||Column1||';')<>0
Run Code Online (Sandbox Code Playgroud)

  • “INSTR”不是可识别的内置函数名称。在我的 SQL Server 中。 (4认同)

Ana*_*nis 5

实现问题中提到的最简单的方法之一是将CONTAINS与 NEAR 或“~”一起使用。例如,以下查询将为我们提供专门包含 word1、word2 和 word3 的所有列。

SELECT * FROM MyTable WHERE CONTAINS(Column1, 'word1 NEAR word2 NEAR word3')

SELECT * FROM MyTable WHERE CONTAINS(Column1, 'word1 ~ word2 ~ word3')
Run Code Online (Sandbox Code Playgroud)

此外,CONTAINSTABLE 根据“word1”、“word2”和“word3”的接近程度返回每个文档的排名。例如,如果文档包含句子“The word1 is word2 and word3”,则其排名会很高,因为这些术语比其他文档中的术语彼此更接近。

我们还可以使用proximity_term来查找单词在列短语内的特定距离内的列。

  • 很好的答案,但请注意,如果表或视图没有全文索引,这将不起作用。`Contains()` 将抛出错误:`无法在表或索引视图 'TABLENAME' 上使用 CONTAINS 或 FREETEXT 谓词,因为它没有全文索引。` (7认同)