1

ユーザーがデータベースからレコードを取得するインターフェイスを構築しました。ユーザーには、0 個以上のフィルターを指定するオプションがあります。A、B、C、D の 4 つのフィルターがあります (これらが特定のテーブルのフィールドであるとしましょう)

私のクエリは次のようになります。

select * from table 
where (A = v1 or B = v2 or C = v3) and D = v4

クエリを作成する方法を考えていますが、特定のフィルターが指定されている場合は適用され、指定されていない場合は無視されます。しかし、これは 16 のケースすべてに当てはまるはずです。

これまでに思いついたのは、次の方法です。

select * from table
where (
    (A = v1 and 1)
    or (B =  v2 and 1)
    or (C = v3 and 1)
    )
    and D = v4

v1またはその他の値が指定されていない場合は、-1 に設定されます。したがって、それらが指定されていない場合は、他のフィルター (A、B、C の中から) が使用されるため、単純に無視されます。ただし、A、B、および C のいずれも指定されていない場合、これは失敗します。その場合、false は D と Anded であり、D は適用されません。

この場合、where 句を使用する方法はありますか? 私は、コードを介して句を追加するか追加しないかで、これに対するプログラムによる解決策にもオープンですが、私はこの方法を好みます。そして、多くの if-else ステートメントを持ちたくありません。

ありがとうございました!

4

3 に答える 3

1

caseコンストラクトの使用について

  select * 
  from table
  where (A = CASE WHEN v1 IS NOT NULL THEN v1 else '' END)
            OR (B =  CASE WHEN v2 IS NOT NULL THEN v2 else '' END)
            OR (C = CASE WHEN v3 IS NOT NULL THEN v3 else '' END)
            OR (CASE WHEN v1 is null and v2 is null and v3 is null then 1 else 0 end)
  and D = v4
于 2012-06-12T07:38:06.077 に答える
0

データベースは、動的 where 節を最適化するのに苦労しています。通常、最初の呼び出しに最適な計画を作成します。したがって、最初の検索がフィルター A と B の場合、クエリ プランはそのために最適化されます。フィルター C と D を使用している場合でも、次のクエリでもそのプランが使用されます。コードに where 句を追加すると、パフォーマンスが大幅に向上する傾向があります。

しかし、それは可能です、例えば:

where  (
           A = @FilterAValue
           or B = @FilterBValue
           or C = @FilterCValue
       )
       and D = coalesce(@FilterDValue, D)

そして、FilterXValueパラメーターを使用してフィルターを切り替えることができます。A、B、または C のフィルターが の場合、nullの他の部分はor引き続き評価されます。 の場合にのみ真となるA = null or B = 1と同じです。unknown or B = 1B = 1

于 2012-06-12T07:39:10.093 に答える
0

v1-がv4検索対象の値であり、それらすべてが-1指定されていない場合は、次のように実行できます。

SELECT
  *
FROM
  table
WHERE
  (
    (A = v1 OR -1 = v1)
  or 
    (B =  v2 OR -1 = v2)
  or 
    (C = v3 OR -1 = v3)
  )
AND
  (D = v4 OR -1 = v4)
于 2012-06-12T07:40:51.207 に答える