使用SQL Server过滤多选框

时间:2009-01-05 19:05:26

标签: sql sql-server listbox

我需要根据多选列表框中的选择从sql server过滤结果集。我已经想过做一个instring以确定行值是否存在于所选的过滤器值中,但是这很容易发生部分匹配(例如Car匹配Carpet)。

我还经历了将字符串拆分成表格并基于此加入/匹配,但我对如何执行该操作有所保留。

看到这是一个看似常见的任务,我正在寻求Stack Overflow社区的一些反馈,也许还有一些关于解决这个问题的最常用方法的建议。

3 个答案:

答案 0 :(得分:4)

我通过编写一个表值函数(我们使用2005)来解决这个问题,该函数采用分隔字符串并返回一个表。然后,您可以加入或使用WHERE EXISTS或WHERE x IN。我们还没有完成压力测试,但由于使用有限且物品数量相当少,我认为性能应该没问题。

以下是其中一项功能,作为您的起点。我还编写了一个专门接受查找表中ID值的分隔的INT列表等等。

另一种可能性是将LIKE与分隔符一起使用以确保忽略部分匹配,但是不能使用索引,因此对于任何大型表,性能都会很差。例如:

SELECT
     my_column
FROM
     My_Table
WHERE
     @my_string LIKE '%|' + my_column + '|%'

/*
    Name:       GetTableFromStringList
    Description:    Returns a table of values extracted from a delimited list
    Parameters:
            @StringList - A delimited list of strings
            @Delimiter - The delimiter used in the delimited list

    History:
    Date        Name            Comments
    ----------  -------------   ----------------------------------------------------
    2008-12-03  T. Hummel   Initial Creation
*/
CREATE FUNCTION dbo.GetTableFromStringList
(
    @StringList VARCHAR(1000),
    @Delimiter  CHAR(1) = ','
)
RETURNS @Results TABLE
(
    String  VARCHAR(1000)   NOT NULL
)
AS
BEGIN
    DECLARE
        @string     VARCHAR(1000),
        @position   SMALLINT

    SET @StringList = LTRIM(RTRIM(@StringList)) + @Delimiter
    SET @position = CHARINDEX(@Delimiter, @StringList)

    WHILE (@position > 0)
    BEGIN
        SET @string = LTRIM(RTRIM(LEFT(@StringList, @position - 1)))

        IF (@string <> '')
        BEGIN
            INSERT INTO @Results (String) VALUES (@string)
        END

        SET @StringList = RIGHT(@StringList, LEN(@StringList) - @position)
        SET @position = CHARINDEX(@Delimiter, @StringList, 1)
    END

    RETURN
END

答案 1 :(得分:1)

  

我一直在想做一个   instring确定行值是否为   存在于选定的过滤器值中,   但这很容易发生部分匹配   (例如汽车匹配地毯)

听起来,您不会在列表框中包含唯一ID或主键作为值的一部分。理想情况下,每个选项都有一个唯一的标识符,该标识符与您要搜索的表中的列相匹配。如果您的列表框如下所示,那么您将能够专门针对汽车进行过滤,因为您将获得唯一值3。

<option value="3">Car</option>
<option value="4">Carpret</option>

然后你只需构建一个where子句,它将允许你找到你需要的值。


更新,回答评论。

  

我如何进行相关加入   考虑到用户可以选择   和任意数量的选项   列表框? SELECT * FROM tblTable   在tblTable.FK =?上加入tblOptions该   这里的问题是我需要加入   多个值。

我回答了类似的问题here

一种方法是构建临时表,并将每个选定的选项作为一行添加到临时表中。然后你只需要加入你的临时表。

如果你想简单地动态创建你的sql,你可以做这样的事情。

SELECT * FROM tblTable WHERE option IN (selected_option_1, selected_option_2, selected_option_n)

答案 2 :(得分:0)

我发现一个CLR表值函数,它接受你的分隔字符串并在字符串上调用Split(将数组作为IEnumerable返回)比在T-SQL中编写的任何东西都更高效(当它开始崩溃时你在分隔列表中有大约一百万个项目,但这比T-SQL解决方案要远得多。)

然后,您可以加入桌面或查看EXISTS。