Condition that decides whether to execute WHERE or not - sql

I have a really big stored procedure and I'd like to include a WHERE clause at the end to be executed just in case that #myparameter=1. I don't want the stored procedure to pay any attention to the WHERE clause when #myparameter=0. Is there any way to do this with CASE or something like that?

WHERE #myparameter=0 OR (insert the current conditions here)

add a modified version of where instead of yours
where (#myparemeter = 0 or (#myparameter = 1 and (your where conditions here)))

If you really want to use CASE, something like this ...
WHERE
CASE
WHEN (#myparameter=0) THEN 1
WHEN (#myparameter=1) AND (rest of where clause) THEN 1
ELSE 0
END = 1

Related

How to implement nested CASE statements in a SQL Select of a stored procedure?

I have a SELECT statement from a temp table in a stored procedure that selects these two columns:
DECLARE #Mode INT
CASE
WHEN t.Descr = '-- Prior Balance --'
THEN ''
ELSE t.ChgAmount
END AS ChgAmount,
CASE
WHEN t.Descr = '-- Prior Balance --'
THEN ''
ELSE t.PayAmount
END AS PayAmount,
I want to conditionally return those two columns differently depending on the value of #Mode, specifically if it is equal to 7.
I'm getting confused about the levels of nesting that I need and the formatting of doing this.
So far I have tried something like this:
CASE
WHEN #Mode = 7
THEN
CASE
WHEN t.TranDate > #Due
THEN t.ChgAmount
END
END AS CurrentCharges,
CASE
WHEN t.Descr = '-- Prior Balance --'
THEN ''
ELSE t.ChgAmount
END AS ChgAmount,
CASE
WHEN t.Descr = '-- Prior Balance --'
THEN ''
ELSE t.PayAmount
END AS PayAmount,
The above SELECT might work, but it would stil return the extra column. How should I nest the other, original, CASE statement for the ChgAmount?
First, let's clarify in abstract terms that in the following pseudo-code
If X then
Case 1
If Y then
Case 2
Else
Case 3
End If
Else
Case 4
End If
Case 1 is equivalent to "X is true"
Case 2 is equivalent to "X is true and Y is true"
Case 3 is equivalent to "X is true and Y is false"
Case 4 is equivalent to "X is false"
Furthermore, let's clarify that case-when criterias are logically very similar to our pseudo-code presented above of if-then, hence, you can apply composite criteria instead of nesting case-when if you prefer that, but also, you can implement nested case-when criterias, it's a matter of style.
As a result, you will need to formulate the logic you want to apply, by asking yourself the following questions:
do I need the same number of fields in my different cases? (if not, then you will probably need to write different queries in different cases)
what cases do I have for my fields if #Mode is 7?
what cases do I have for my fields if #Mode is not 7?
how can I merge my criterias in the points above into coherent (composite) criterias that would not require nesting?
If you answer these questions as an edit to this question, then we will be able to more properly answer your questions than the general terms I'm using in this answer and we may provide code for you as well. However, if you think this through, then you might also be able to implement this in a not nested way. And, if you are able to understand this as far as to implement it into a not nested way, then you could transform that implementation into a nested implementation as well.

Can I use different selection comparisons based on a passed value in SQL?

I wasn't really sure of the best wording for the question but here is my dilemma:
I am passing a value to a sql query as #district. This value may be the exact district but it also has the possibility of being a value that should create a set of multiple districts. So if I pass 002 I want the WHERE clause to say I.Offense_Tract = #district. If I pass Other I want the WHERE clause to say I.Offense_Tract in (). What I am trying to do is something like:
AND
CASE
WHEN #district = "Other" THEN I.Offense_Tract in ('BAR','COL','GER','MEM','MIL','JAIL','JAILEAST','SCCC','1USD','2USD')
ELSE I.Offense_Tract = #district
END
But this doesn't work. The problem, restated, is if the value passed is anything other than Other, I just want it to be =. If Other is passed, I want it to be IN.
You don't need the CASE expression.
You can apply this logic with operators AND and OR:
AND (
(#district = 'Other' AND I.Offense_Tract IN ('BAR','COL','GER','MEM','MIL','JAIL','JAILEAST','SCCC','1USD','2USD'))
OR
(#district <> 'Other' AND I.Offense_Tract = #district)
)
Note that, in databases like MySql, Postgresql and SQLite, your code would work as it is.

Defining the (alias) name of a field

I've been looking over some code in an old Classic ASP system of ours that builds its own SQL within the stored procedure and then executes it {shudders}.
Several of the SELECTion lines contain an assignment, similar to:
SELECT
my_field = CASE WHEN value = whatever THEN 1 ELSE 0 END
...
Is there any difference (or anything I need to be aware of) between this and using a standard AS alias?...
SELECT
CASE WHEN value = whatever THEN 1 ELSE 0 END AS my_field
...
No, the following code is all synonymous:
SELECT one = 1;
SELECT 1 one;
SELECT 1 AS one;
SELECT 'one' = 1; --this is deprecated, don't use it.
Which you use (apart from the last), is normally down the preference. Personally, I use AS. One reason is I can then easily tell queries that return datasets, and those that assign values to variables a part.
The 2 examples that you have given are identical. However, when you go through the old code you might also find a variant with an # sign before my_field, like this:
SELECT
#my_field = CASE WHEN value = whatever THEN 1 ELSE 0 END
In this case a varable called #my_field is assigned a value, but nothing is SELECTed. This you can not rewrite to the other syntax using AS #myfield.

SQL case when behaves like if else if

When I write an sql case when statement(s), does it function like an if, if ,..if logic or if, else-if , else-if, else logic?
i.e if the condition matches case #1, will it still evaluate the other cases?
Any self-respecting database will short circuit, but you didn't mention which database you are using. So, try it: select case when 1=1 then 1 else 1/0 end and see.
The case statement evaluates the when conditions in order. It stops at the first condition that evaluates to true. This is ANSI standard behavior and, as far as I know, all databases support the case statement in this way.

Using IF/THEN or CASE within a WHERE clause in SQL

I have been assigned the task of updating the EEO survey and reporting for a mid sized company. I am working on a stored procedure to populate a report from. All is good but for a syntax problem. One of the requirements is to dynamically allow the user to filter the results by the EEO Job Group Number. When the report page loads, it populates the table with all Job Groups Combined. I have placed a DropDownList on the page that allows the user to choose one of the 10 EEO Job Groups or by default, All Job Groups Combined (no filtering). The DDL executes postback and populates a parameter; #intEeoJobGroupID. There is not actually a 0 ID value in the table, just in the DDL. I want the (usp) query to use one set of WHERE statements if the passed parameter #intEeoJobGroupID = 0, and another if #intEeoJobGroupID <> 0. (Effectively adding another AND statement if the parameter <> 0)
I want to return the count of how many EEO records meet the requirements of the query. I have tried IF/THEN, and CASE, in many different formats, and can not seem get the syntax right. In the example below I get the message "Incorrect Syntax near the first = in the THEN statement, as well as the keyword ELSE.
Any hints?
DECLARE #intEeoJobGroupID INT
SELECT
COUNT (E.intEeoID)
FROM
dbo.NewEEO AS E
WHERE
CASE WHEN #intEeoJobGroupID = 0
THEN
E.intGenderID = 1
AND E.intRaceID = 2
ELSE
E.intGenderID = 1
AND E.intRaceID = 2
AND E.intEeoJobGroupID = #intEeoJobGroupID
You're making it way too complicated:
WHERE E.intGenderID = 1
AND E.intRaceID = 2
AND (E.intEeoJobGroupID = #intEeoJobGroupID OR #intEeoJobGroupID = 0)
As someone else already mentioned, your existing syntax was missing an "END", but it still won't work with that added. To get this right in the future, one thing you can try to do is remember that CASE expressions in SQL are just that: expressions. They are not statements, as you might be used to with if statements in c# code. You don't use CASE for flow control, to define blocks as you were trying to do.
Don't try to return a boolean from a CASE statement. Instead return some value that is then checked outside the CASE statement (and so then resulting in a boolean).
CASE WHEN #mode = 1 THEN CASE WHEN <Condition1> THEN 1 ELSE 0 END
WHEN #mode = 2 THEN CASE WHEN <Condition2> THEN 1 ELSE 0 END
END
=
1
Note: This will create Awful execution/explain plans and totally nerf performance. You are better using real IF blocks and real queries, or possibly unions...
IF #mode = 1
SELECT foo FROM bar WHERE <Condition1>
ELSE IF #mode = 2
SELECT foo FROM bar WHERE <Condition2>
Or...
SELECT foo FROM bar WHERE <condition1> AND #mode = 1
UNION ALL
SELECT foo FROM bar WHERE <condition2> AND #mode = 2
In order to prevent massive duplication of code, you may find that encapsulating the bulk of the query in a VIEW is helpful.
You can't make a comparison the result of a case condition. If you're using case in a where clause, it needs to be on one side of the operator:
CASE #case_value
WHEN 0 THEN
some_column
ELSE
some_other_column
END = #some_value
However, if you try to make your actual condition fit this rule, you'll end up not using the case statement at all, as #Joel point out.
You have to add
end
in the end of case.