2

複数選択リスト ボックスからの選択に基づいて、SQL サーバーから結果セットをフィルター処理する必要があります。選択したフィルター値に行の値が存在するかどうかを判断するために instring を実行するというアイデアを実行しましたが、部分一致 (Car と Carpet の一致など) になりがちです。

文字列をテーブルに分割し、それに基づいて結合/照合も行いましたが、それがどのように実行されるかについては予約があります。

これは一見一般的なタスクであるため、スタック オーバーフロー コミュニティにフィードバックを求めており、この問題を解決するために最も一般的に使用されているアプローチについていくつかの提案を求めています。

4

3 に答える 3

4

区切られた文字列を取り、テーブルを返すテーブル値関数 (2005 を使用しています) を作成することで、これを解決しました。その後、それに参加するか、WHERE EXISTS または WHERE x IN を使用できます。まだ完全なストレス テストは行っていませんが、使用が制限され、項目の数がかなり少ないため、パフォーマンスは問題ないと思います。

以下は、出発点としての機能の 1 つです。また、ルックアップ テーブルなどの ID 値の INT の区切られたリストを具体的に受け入れるように作成したものもあります。

もう 1 つの可能性は、デリミタで 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
于 2009-01-05T19:31:40.107 に答える
1

選択したフィルター値に行の値が存在するかどうかを判断するために instring を実行するというアイデアを実行しましたが、部分的な一致が発生する傾向があります (たとえば、Car は Carpet と一致します)。

リスト ボックスの値の一部として、一意の ID や主キーを含めていないように思えます。理想的には、各オプションには、検索対象のテーブルの列と一致する一意の識別子があります。リストボックスが以下のようなものである場合、一意の値 3 を取得するため、特に車をフィルタリングできます。

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

次に、必要な値を見つけることができる where 句を作成します。


コメントに答えるために更新されました。

ユーザーがリストボックスから任意の数のオプションを選択できることを考慮して、関連する結合を行うにはどうすればよいですか? SELECT * FROM tblTable JOIN tblOptions ON tblTable.FK = ? ここでの問題は、複数の値を結合する必要があることです。

ここで同様の質問に答えました。

1 つの方法は、一時テーブルを作成し、選択した各オプションを行として一時テーブルに追加することです。次に、一時テーブルに結合するだけです。

単にSQLを動的に作成したい場合は、次のようなことができます。

SELECT * FROM tblTable WHERE option IN (selected_option_1, selected_option_2, selected_option_n)
于 2009-01-05T20:10:33.803 に答える
0

区切られた文字列を受け取り、文字列に対して Split を呼び出す (配列を IEnumerable として返す) CLR テーブル値関数は、T-SQL で記述されたものよりもパフォーマンスが高いことがわかりました (周りにあると壊れ始めます)。区切りリストには 100 万個のアイテムがありますが、これは T-SQL ソリューションよりもはるかに優れています)。

そして、テーブルに参加したり、EXISTS で確認したりできます。

于 2009-01-05T21:32:02.517 に答える