如何最小化sql选择?

时间:2013-11-06 11:11:10

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

我有一系列像这样的词:

$word1 = array('test1','test2','test3','test4','test5',...,'test20');

我需要在我的表格中搜索text列中至少包含其中一个字词的每一行。到目前为止,我有这个SQL查询:

SELECT * FROM TABLE WHERE text LIKE '$word1[0]' OR text LIKE '$word1[1]' 
OR ... OR text LIKE '$word1[20]'

但我发现这种设计效率不高。有没有办法可以缩短这个查询,这样我就不需要写出where子句中的每个单词了?

示例SELECT * FROM TABLE WHERE text IN ($word1)

P.S。:这是我正在寻找的一个例子,而不是我可以运行的实际查询。

4 个答案:

答案 0 :(得分:2)

如果您使用表变量而不是列表来存储单词,那么您可以使用以下内容:

DECLARE @T TABLE (Word VARCHAR(255) NOT NULL);
INSERT @T (Word)
VALUES ('test1'), ('test2'), ('test3'), ('test4'), ('test5'), ('test20');

SELECT  * 
FROM    TABLE t
WHERE   EXISTS
        (   SELECT  1
            FROM    @T
            WHERE   t.Text LIKE '%' + word + '%'
        );

您还可以创建一个表类型来存储它,然后您可以根据需要将其作为参数传递给存储过程:

CREATE TYPE dbo.StringList (Value VARCHAR(MAX) NOT NULL);
GO
CREATE PROCEDURE dbo.YourProcedures @Words dbo.StringList READONLY
AS
    SELECT  * 
    FROM    TABLE t
    WHERE   EXISTS
            (   SELECT  1
                FROM    @Words w
                WHERE   t.Text LIKE '%' + w.word + '%'
            );
GO
DECLARE @T dbo.StringList;
INSERT @T (Value)
VALUES ('test1'), ('test2'), ('test3'), ('test4'), ('test5'), ('test20');

EXECUTE dbo.YourProcedure @T;

有关详情,请参阅MSDN上的table-valued Parameters


修改

我可能误解了您的要求,因为您使用LIKE但没有外卡操作符,在这种情况下您只能使用IN,但我仍然建议使用表来存储您的值:

DECLARE @T TABLE (Word VARCHAR(255) NOT NULL);
INSERT @T (Word)
VALUES ('test1'), ('test2'), ('test3'), ('test4'), ('test5'), ('test20');

SELECT  * 
FROM    TABLE t
WHERE   t.Text IN (SELECT Word FROM @T);

答案 1 :(得分:0)

一种解决方案可能是:

  1. 在数据库中创建一个表,其中搜索的单词位于一个名为word的列中(通过示例) - 如果需要,可以使用通配符
  2. 使用此类请求

    SELECT * FROM TABLE,FILTER_TABLE WHERE TABLE.text LIKE FILTER_TABLE.word

答案 2 :(得分:0)

您可以像这样使用SELECT而不声明数组:

SELECT * FROM TABLE WHERE text IN ('test1', 'test2', 'test3', 'test4', 'test5')

答案 3 :(得分:0)

虽然目前我无权访问SQL Server 2008而SQLfiddle似乎生病了,但似乎可以使用table value constructor来简化表达式;

SELECT * FROM test
JOIN (SELECT w FROM (VALUES('word1'), ('word2'), ('word3'), ('word4')) AS a(w)) a
  ON test.text LIKE '%'+a.w+'%';

...将在测试表中的文本列中搜索列为值的单词。如果您不想要多个单词匹配的行重复,则只需向选择中添加DISTINCT即可。

请注意,如果您要进行大量搜索,可能需要查看fulltext indexingLIKE查询以这种方式查找字符串中的字词使用任何索引,除非数据已经在内存中,否则很可能会很慢。