SQL:查找Column包含所有给定单词的行

时间:2010-09-27 14:37:37

标签: sql sql-server sql-server-2008

我有一些列EntityName,我希望用户能够通过输入以空格分隔的单词来搜索名称。该空间被隐式地视为“AND”运算符,这意味着返回的行必须具有指定的所有单词,并且不一定按给定顺序。

例如,如果我们有这样的行:

  1. abba nina pretty balerina
  2. acdc你整晚都在震撼我
  3. ......你是我
  4. 梦幻剧院就是你的全部。
  5. 当用户输入:me youyou me(结果必须相同)时,结果包含第2行和第3行。

    我知道我可以这样:

    WHERE Col1 LIKE '%' + word1 + '%'
      AND Col1 LIKE '%' + word2 + '%'
    

    但我想知道是否有更优化的解决方案。

    CONTAINS需要一个全文索引,由于各种原因,它不是一个选项。

    对于这些案例,也许Sql2008有一些内置的,半隐藏的解决方案?

6 个答案:

答案 0 :(得分:3)

我唯一能想到的就是编写CLR函数进行LIKE比较。这应该快很多倍。

更新:现在我考虑一下,CLR无济于事。另外两个想法:

1 - 尝试索引Col1并执行此操作:

WHERE (Col1 LIKE word1 + '%' or Col1 LIKE '%' + word1 + '%')
  AND (Col1 LIKE word2 + '%' or Col1 LIKE '%' + word2 + '%')

根据最常见的搜索(以子字符串开头),这可能会有所改进。

2 - 添加您自己的全文索引表,其中每个单词都是表格中的一行。然后你可以正确索引。

答案 1 :(得分:3)

功能

 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
 )

查询

 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.Col1 LIKE '%' + F1.Data + '%'
      LEFT JOIN @FilterTable F2 ON T.Col1 NOT LIKE '%' + F2.Data + '%'
 WHERE
      F2.Data IS NULL

来源:SQL SELECT WHERE field contains words

答案 2 :(得分:2)

答案 3 :(得分:2)

无论如何,你最终会得到全表扫描。

整理可以显然有很大的不同。 Kalen Delaney在书“Microsoft SQL Server 2008 Internals”中说:

  整理可以产生巨大的差异   什么时候SQL Server几乎要看   字符串中的所有字符。对于   例如,请看以下内容:

SELECT COUNT(*) FROM tbl WHERE longcol LIKE '%abc%'
     

使用二进制排序规则可以比非二进制Windows排序规则快10倍或更多。使用varchar数据时,SQL排序规则的执行速度比Windows排序规则快7到8倍。

答案 4 :(得分:1)

WITH Tokens AS(SELECT 'you' AS Token UNION ALL SELECT 'me')
SELECT ...
FROM YourTable AS t
WHERE (SELECT COUNT(*) FROM Tokens WHERE y.Col1 LIKE '%'+Tokens.Token+'%') 
 = 
(SELECT COUNT(*) FROM Tokens) ;

答案 5 :(得分:0)

理想情况下,这应该在如上所述的全文搜索的帮助下完成。 但, 如果您没有为数据库配置全文本,则这是一种性能密集型解决方案,用于进行优先的字符串搜索。

{{1}}