English 中文(简体)
使用 SQL Server 的多选框进行过滤
原标题:
  • 时间:2009-01-05 19:05:26
  •  标签:

我需要根据多选列表框的选择来过滤来自SQL Server的结果集。我已经考虑过使用instring来确定行值是否存在于所选筛选值中,但这容易出现部分匹配(例如,Car匹配Carpet)。

我也尝试将字符串分割成表格,基于此进行连接/匹配,但我对其性能有所保留。

由于这似乎是一个常见的任务,我寻求 Stack Overflow 社区的反馈和可能几个对解决此问题最常用的方法的建议。

最佳回答

我通过编写一个表值函数(我们使用的是2005版)来解决这个问题,该函数接受一个分隔符字符串并返回一个表格。然后您可以连接到该表格或使用WHERE EXISTS或WHERE x IN。我们尚未进行全面压力测试,但在有限的使用和相当小的项目集中,我认为性能应该是可以的。

以下是一个起点功能。我还编写了一个来专门接受分隔符分隔的INT列表,用于查找表等ID值。

另一种可能性是使用带界定符的LIKE来确保忽略部分匹配,但无法使用索引,因此对于任何大型表格,性能会很差。例如:

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

Sorry, there is no text provided for me to translate. Can you please provide the text you want me to translate?

/*
    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  TSorry, there is no text provided for me to translate. Can you please provide the text you want me to translate? Hummel   Initial Creation
*/
CREATE FUNCTION dboSorry, there is no text provided for me to translate. Can you please provide the text you want me to translate?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
问题回答

I ve been through the idea of doing an instring to determine if the row value exists in the selected filter values, but that s prone to partial matches (e.g. Car matches Carpet)

听起来好像你没有包括唯一标识符或可能是主键作为在你的列表框中的值的一部分。理想情况下,每个选项都将有一个唯一的标识符,该标识符与您正在搜索的表中的列匹配。如果您的列表框如下所示,则您将能够特别过滤汽车,因为您将获得唯一值3。

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

然后您只需要构建一个where子句,让您能够找到所需的值。


更新,以回答评论。

How would I do the related join considering that the user can select and arbitrary number of options from the list box? SELECT * FROM tblTable JOIN tblOptions ON tblTable.FK = ? The problem here is that I need to join on multiple values.

我在这里回答了一个类似的问题。

一种方法是建立一个临时表,并将每个选择的选项作为一行添加到临时表中。然后,您只需将其与临时表连接即可。

如果您想要动态地创建您的SQL语句,您可以尝试以下方式。

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

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

然后,您可以加入表格或检查是否存在。





相关问题
热门标签