Instead of a case expression, you could simply use OR
:
WHERE (@End = 310 AND m.LONR = 310)
OR (@End <> 310 AND m.LONR <> 310)
It is worth noting that neither predicate will evaluate to true in the case of NULL
values, so if either the variable or the column are nullable you may wish to use:
WHERE (@End = 310 AND m.LONR = 310)
OR (ISNULL(@End, 0) <> 310 AND ISNULL(m.LONR, 0) <> 310);
If m.LONR
is indexed, then it would almost certainly be beneficial to split the cases up using either IF
:
IF (@End = 310)
BEGIN
SELECT <columns>
FROM <tables>
WHERE m.LONR = 310;
END
ELSE
BEGIN
SELECT <columns>
FROM <tables>
WHERE m.LONR <> 310;
END
Or using UNION ALL
SELECT <columns>
FROM <tables>
WHERE m.LONR = 310
AND @End = 310;
UNION ALL
SELECT <columns>
FROM <tables>
WHERE m.LONR <> 310
AND @End <> 310; --OR ISNULL(@End, 0) <> 310 to deal with NULLs
The reason for this is that SQL Server will create a plan based on @End
being unknown, therefore does not know at compilation time whether it will be filtering by:
m.LONR = 310
or
m.LONR <> 310
Therefore it cannot effectively plan whether an index seek, or table scan will be more efficient. Separating the logic will allow the most efficient plan to be used for each scenario.