Problem with field not equal to null in case statement - sql

So I have EXISTS in huge query which looks like this:
EXISTS(
SELECT
*
FROM
ExistTable
WHERE
ExTableFieldA = #SomeGuid AND
ExTableFieldB = MainTableFieldB AND
ExTableFieldA <> (
CASE
WHEN MainTableFieldZ = 10 THEN MainTableFieldYYY
ELSE NULL
END
)
)
The problem comes from ELSE part of CASE statement, this ExTableFieldA <> NULL will be always false. I could easily write another parameter #EmptyGuid and make it equal to '00000000-0000-0000-0000-000000000000' and everything will work but is this the best approach ?
Pretty much I want to execute another check into the exist for the small size of the records which return the "main" query.

How about removing the case and just using boolean logic?
WHERE ExTableFieldA = #SomeGuid AND
ExTableFieldB = MainTableFieldB AND
(MainTableFieldZ <> 10 OR ExTableFieldA <> MainTableFieldYYY)
I would also recommend that you qualify the column names by including the table alias.
Note: This does assume that MainTableFieldZ is not NULL. If that is a possibility than that logic can easily be incorporated.

ELSE NULL is implied even if you don't list it, but you could use ISNULL here.
ISNULL(ExTableFieldA,'') <> (
CASE
WHEN MainTableFieldZ = 10 THEN MainTableFieldYYY
ELSE ''
END
)
You may need to use some other value like 9999 instead of ''

Related

How to handle NULL values in WHERE clause and change target column based upon its encounter

I need the WHERE clause to change what column it is evaluating when NULL is encountered. For instance I'm trying to do something like this:
SELECT *
FROM customer c
WHERE CASE WHEN c.cust_id_1(#variable) IS NOT NULL THEN c.cust_id_1 = #variable
ELSE CASE WHEN c.cust_id_2(#variable) IS NOT NULL THEN c.cust_id_2 = #variable
ELSE c.cust_id_3 = #variable
Is something like this possible? One of the 3 cust_id's will not be NULL.
That seems like less than optimal table design, but isn't a simple COALESCE where you're after?
WHERE #variable = COALESCE(cust_id_1, cust_id_2, cust_id_3);
You don't need a CASE expression for this, you just need logical operators
SELECT *
FROM customer c
WHERE
(c.cust_id_1 IS NOT NULL AND c.cust_id_1 = #variable)
OR
(c.cust_id_2 IS NOT NULL AND c.cust_id_2 = #variable)
OR
(c.cust_id_3 IS NOT NULL AND c.cust_id_3 = #variable)

Case statement in where clause using not like and is not null

I'm pulling data from an existing table using a stored procedure that has some yes or no choices that the user picks on the front end through a checkbox. I want to limit writing a bunch of different If statements for every choice they make.
This portion of my where clause works. Data is either Y or N for this column.
Where... and IsSigned = Case When #IncludeSigned = 'Y' then IsSigned else 'N' end
I would like to add to the where using is not null and not like if this is possible between the square brackets. So far I have
and SignatureType = case when #IncludeElectronic = 'Y' then Type else [NOT like electronic] end
also
and ReviewDate = Case When #HasReviewDate = 'Y' then [ReviewDate is not null] else null end
This may help you use AND/OR instead of case
where (ReviewDate is not null or #HasReviewDate = 'Y' ) And (....)
ie when #HasReviewDate = 'Y' query will return the records with ReviewDate is not null
and when #HasReviewDate != 'Y' then query will return the records with ReviewDate is null
think of it this way:-
Your first case statement has two possible results:-
IsSigned = 'Y'
IsSigned = 'N'
Your subsequent ones have problems as they don't make sense syntactically. So the second one as written returns
SignatureType = Type
SignatureType = [NOT like electronic]
and your third:
ReviewDate = [ReviewDate is not null]
ReviewDate = null end
SO the operator has to be before the case statement and apply to all of the results of the case statement.
For example
WHERE myfield not like CASE WHEN thatfield=1 THEN 'Fish' ELSE 'Chips END
would produce either
myfield not like 'Fish'
myfield not like 'Chips'
I believe you can not use in this way, apart of that, the impact that is not like can have inside your query can be high, my recommendation changes the strategy that you are using.

Case inside 'where' section that changes the condition of an AND statement

I am creating a store procedure and i am wondering how can i add a case block in an Add statement inside the where statement.That case statement checks an input parameter and depending its value it will change the condition from greater that to smaller than and of course be added to the add conditions
So a part of the query is like:
WHERE
AND BM.Example1 IS NOT NULL
AND BM.Example2 IS NOT NULL
AND ( Case When #inputParamter= 'A' THEN AND BM.Example < 0 ELSE And BM.Example> 0 )
ORDER BY 'SEG' ASC, 'CCY' ASC
So by this approach i am thinking to extract an add statement depending on the input parameter but unfortunately i keep getting syntax errors.
Is that possible?
Yepp, just use this:
AND (( #inputParamter= 'A' AND BM.Example < 0) OR ( #inputParamter<>'A' AND BM.Example> 0) )
However, be carefull with NULL, you have to put it in the logic as a third option.
here is a similar answer using case
AND ( Case When #inputParamter = 'A' AND BM.Example < 0 THEN 'Y'
When #inputParamter <> 'A' AND BM.Example > 0 THEN 'Y' ELSE 'N' END = 'Y')

Dynamic where clause based on variable

I am working on a select statement in SQL and am running into issues trying to create a where clause that includes a case statement or an if else statement. I want to select records based on the value of a variable. If the variable is 'True' then only return records from the select statement where a column is null. If the variable is not 'True' then return all records regardless if that columns is null.
Any tips on how to do this?
Below is a simple example of what i am trying to do:
declare #option1 as varchar(5)
--This can be True or False so to test i just put the Set option below
set #option1 = 'True'
Select a,b,c,d...
from ...
where d = case when #option1 = 'True' then NULL End
This is the part where i do not know what to do. I only need to filter out the records if the variable is 'True' so not sure what to put in the else section of the case.
You can't test for d = NULL as your CASE statement does because that will always return false since NULL is not equal to NULL (unless you set ANSI_NULLS to 'off').
The simplest thing to do would be to change the WHERE clause to this:
WHERE #option1 = 'False' OR d IS NULL
If you prefer to use a CASE statement for some reason, you can write it like this:
WHERE 1 = CASE WHEN #option1 = 'False' THEN 1
WHEN #option1 = 'True' AND d IS NULL THEN 1
ELSE 0
END
This:
UPDATE: PinnyM has straightened me out on this. I am leaving my embarrassing logically flawed argument here for the education of the masses. The solution I propose below after "Try this" is certainly still valid, but PinnyM's solutions is by far more elegant and should be used.
WHERE #option1 = 'False' OR d IS NULL
Will always return all the results given his current select statement (assuming #Option1 is simply a flag parameter passed in).
Try this:
SELECT a, b, c, d
WHERE
-- Returns only rows where d is null (if #Option1 is True)
(#Option1 = 'True' AND d IS NULL)
OR
-- returns all the rows (if #Option1 is False)
(#Option1 = 'False')

An expression of non-boolean type specified in a context where a condition is expected, near 'END'

So maybe someone can point me in the right direction of what is causing this error? I've been fighting with this for a couple of hours and searching the web, and I can't figure out what I'm doing wrong here. It's included as part of a stored procedure, I don't know if that matters, if it does I can include that as well. Tables and field names have been changed to protect the innocent... meaning my job. Thanks.
SELECT
/* The fields are here*/
FROM
/* my joins are here */
WHERE
(Table.Field = stuff)
AND
(Table.Field2 = otherstuff)
AND
(Table2.Field3 = someotherstuff)
AND
CASE #param1
WHEN 0 THEN 'Table.Field IS NULL'
WHEN 1 THEN 'Table.Field2 IS NOT NULL'
ELSE ''
END
Thanks for the responses. Technically egrunin was the correct answer for this question, but OMG Ponies and Mark Byers were pretty much the same thing just missing that last piece. Thanks again.
I'm pretty sure the other answers leave out a case:
WHERE
(Table.Field = stuff)
AND
(Table.Field2 = otherstuff)
AND
(Table2.Field3 = someotherstuff)
AND
(
(#param1 = 0 and Table.Field IS NULL)
OR
(#param1 = 1 and NOT Table.Field2 IS NULL)
OR
(#param1 <> 0 AND #param1 <> 1) -- isn't this needed?
)
You are returning a string from your case expression, but only a boolean can be used. The string is not evaluated. You could do what you want using dynamic SQL, or you could write it like this instead:
AND (
(#param1 = 0 AND Table.Field IS NULL) OR
(#param1 = 1 AND Table.Field IS NOT NULL)
)
You can't use CASE in the WHERE clause like you are attempting
The text you provided in the CASE would only run if you were using dynamic SQL
Use:
WHERE Table.Field = stuff
AND Table.Field2 = otherstuff
AND Table2.Field3 = someotherstuff
AND ( (#param1 = 0 AND table.field IS NULL)
OR (#param1 = 1 AND table.field2 IS NOT NULL))
...which doesn't make sense if you already have Table.Field = stuff, etc...
Options that would perform better would be to either make the entire query dynamic SQL, or if there's only one parameter - use an IF/ELSE statement with separate queries & the correct WHERE clauses.