OR
を使用して実行できます :
WHERE (@Id > 0 AND Table1.Field = @Id) OR (@Id = 0 AND Table1.Field IN (6,16,18))
プレ>ただし、(あなたが言ったように)
IF/ELSE
を使用することをお勧めします 、このように 2 つの条件を組み合わせると、次善の計画を強制することがよくあります。たとえば、あなたの例では、これを次のようにスキーマに単純化できます:CREATE TABLE T ( ID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY, Field INT NOT NULL, SomeOtherField INT NULL ); GO INSERT T (Field) SELECT Number FROM Master..spt_values CROSS JOIN (VALUES (1), (2), (3)) t (A) WHERE Type = 'P' GO CREATE NONCLUSTERED INDEX IX_T_Field ON T (Field) INCLUDE (SomeOtherField);
プレ>これは、列の 1 つに 0 ~ 2047 の数字をそれぞれ 4 回繰り返して入力するだけです (いくつかのサンプル データの場合)。次に、上記の条件を組み合わせた「IF/ELSE」を使用する 2 つのプロシージャを作成すると、次のようになります。
CREATE PROCEDURE dbo.Test @ID INT AS SELECT ID, Field, SomeOtherField FROM T WHERE (@Id > 0 AND T.Field = @Id) OR (@Id = 0 AND T.Field IN (6,16,18)) GO CREATE PROCEDURE dbo.Test2 @ID INT AS IF @ID = 0 SELECT ID, Field, SomeOtherField FROM T WHERE T.Field IN (6, 16, 18) ELSE SELECT ID, Field, SomeOtherField FROM T WHERE T.Field = @Id GO
プレ>クエリのコンパイルは 1 回しか行われないため (別の方法で明示的に指定しない限り)、オプティマイザはプロシージャに 0 を渡すか ID> 0 を渡すかに応じて異なるプランを選択しません。したがって、次の両方が行われます:
EXECUTE dbo.Test 0; EXECUTE dbo.Test 1;
プレ>このプランを提供します:
2 番目の手順では、最適な実行計画をより正確に見積もることができるため、これを実行します:
EXECUTE dbo.Test2 0; EXECUTE dbo.Test2 1;
プレ>次のプランを提供します:
実際の例は明らかに異なるため、私の主張を証明する例を意図的に作成しました。
IF/ELSE
を使用して多くのコードを複製するのは少し手間がかかります 、しかし多くの場合、それだけの価値があります。