I have a stored procedure and I want implement the following query using Case Statement , but I am not sure how to do it .
pseudocode of what I want is provided here :
declare @PI_X decimal(18);
declare @PI_y decimal (18);
SELECT F1, F2,F3
FROM TABLE T
WHERE
CASE
WHEN @PI_X IS NULL THEN @PI_Y = T.Y
WHEN @PI_Y IS NULL THEN @PI_X = T.X
It seems that using case statement for conditions is not true and its for values
.
NOTE:
I want to run this query in DB2 and SQL server , but really Data Base vendor is not important for me ,using sql dynamic query and (OR) in where clause has a performance hit . and I don't want it. I really like to know how it's possible to achieve such a logic using case in where clause.
Could you please help me to handle this problem . Any help and suggestions would be so appreciated .
I'm not sure why your question is tagged with both SQL Server AND DB2... But I'll assume SQL Server...
declare @PI_X decimal(18);
declare @PI_y decimal (18);
SELECT
T.F1,
T.F2,
T.F3
FROM
TABLE T
WHERE
(@PI_X = T.X OR @PI_X IS NULL)
AND ((@PI_y = T.Y OR @PI_y IS NULL)
OPTION (RECOMPILE); -- Prevent's the forced scan operation cause by the use of "optional" parameters.
The result of a CASE
expression is a value, not an expression. You can't use a CASE
expression to decide which code will run. You can only use it to choose what value will be used with your code.
In this case, you can accomplish your goal like this:
declare @PI_X decimal(18);
declare @PI_y decimal (18);
SELECT F1, F2,F3
FROM TABLE T
WHERE 1 =
CASE
WHEN @PI_X IS NULL AND @PI_Y = T.Y THEN 1
WHEN @PI_X IS NOT NULL AND @PI_Y IS NULL AND @PI_X = T.X THEN 1
ELSE 0 END
You could also try it like this:
declare @PI_X decimal(18);
declare @PI_y decimal (18);
SELECT F1, F2,F3
FROM TABLE T
WHERE coalesce(@PI_X, T.X) = T.X AND coalesce(@PI_y, T.Y) = T.Y
Though this second option might produce unexpected results if @PI_y
might be something other than NULL
when @PI_x
has a value. If you can guarantee one or the other of the two variables will have a value, but never both, then you could also simplify the first option to remove the extra @PI_X IS NOT NULL AND
part of the expression.
You can try out putting the if condition which will be readable however increasing the lines of code.
if(@PI_X IS NULL)
begin
select
....
where
T.Y=@PI_Y
end
else
begin
select
....
where
T.X = @PI_X
end
Instead of using an OR
in the WHERE
clause you could also build 2 separate queries and use IF...ELSE...
to decide which one to use; something along the lines of what Coder1991 suggested. Or you could use a UNION ALL
construction to avoid the IF
and eliminate any branching.
SELECT F1, F2,F3
FROM TABLE T
WHERE @PI_X IS NULL
AND @PI_Y = T.Y
UNION ALL
SELECT F1, F2,F3
FROM TABLE T
WHERE @PI_Y IS NULL
AND @PI_X = T.X