SQL Using CASE to Apply WHERE [duplicate] - sql

This question already has answers here:
SQL Server : check if variable is Empty or NULL for WHERE clause
(6 answers)
Closed 6 months ago.
I'm not sure if CASE is what I actually need to use here, but basically what I am trying to do is apply "WHERE ba.batchid = #batchId" but only if #batchId is not null.
Basically something like this, but this gives an error around the ba.batchid = '2' area ('2' is what the #batchId would come out to).
CASE WHEN '2' != '' THEN ba.batchid = '2' ELSE null END

It helps to think of Case statements as a scalar value. The problem you are experiencing is caused by doing a comparison within the case statement. Basically, you need to pull the comparison out of the case statement.
I'm not sure of the logic you are trying to use, but the following syntax should be correct.
CASE WHEN '2' != '' THEN ba.batchid ELSE null END = '2'
Note that the = '2' is moved to the end. This way, the case statement will return batchid or null depending on the WHEN statement. This value is then compared to '2'.

Try this:
WHERE NULLIF(#batchId, '') IS NOT NULL AND ba.batchid = #batchid
First condition avoids empty('') as well as NULL with #batchid. Second will match the table value.

Take it out of the SELECT part of your statement entirely and put it in the WHERE clause (after FROM)
WHERE ba.batchid = #batchId
AND ba.batchid IS NOT NULL
Note that the AND ba.batchid IS NOT NULL is not necessary here as the first line will filter any nulls. However there are versions of SQL where this is not the case and retaining it in the query still works, hence I have left it in.

Related

Check column IS NULL not working in Case Expression

I am trying to check a column which belongs to View "IS NULL" and it works good with select statement:
SELECT TOP (1000) [Invoice_Number]
,[Invoice_Date]
,[Invoice_Amount]
,[Invoice_CoCd]
,[Invoice_vendor]
,[Invoice_PBK]
,[Invoice_DType]
,[Invoice_DueDate]
,[Invoice_ClgDate] FROM [dbo].[viewABC] where Invoice_PBK IS NULL
Now I have an update statement, where I need to update a column in a table based on NULL in VIEW:
UPDATE cis
SET
cis.InvoiceStatus =
(
CASE
WHEN RTRIM(LTRIM(imd.[Invoice_PBK])) IS NULL THEN
'HELLO'
WHEN RTRIM(LTRIM(imd.Invoice_DType)) = 'RD'
THEN '233' END)
FROM
[dbo.[tblABC] cis,
[dbo].[viewABC] imd
WHERE [condition logic]
These is no issue with where condition, the IS NULL in the CASE expression causing the problem.
Can someone help please?
You may want to just test your Logic piece by piece.
Try
SELECT ISNULL(RTRIM(LTRIM(imd.[Invoice_PBK])),'Hey Im Null')
FROM
[dbo].[tblABC] cis,
[dbo].[viewABC] imd
WHERE [condition logic]
See if you get that String value on your returned column(s) from the Query. Then, build from there. It could be something as simple as the JOIN. Which I'm not a fan of that old syntax but, without more info on this table other than [conditions]. It's hard to just guess an answer for you. You have no detailed evidence that helps us. It very well could be your conditions but, you're saying "condition logic" and that does nothing for the group on this thread.
Looking at this expression:
cis.InvoiceStatus =
CASE
WHEN RTRIM(LTRIM(imd.[Invoice_PBK])) IS NULL THEN
'HELLO'
WHEN RTRIM(LTRIM(imd.Invoice_DType)) = 'RD' THEN
'233'
END
And this symptom:
CIS.InvoiceStatus gets updated with NULL
The obvious conclusion is neither WHEN condition is met, and therefore the result of the CASE expression is NULL.
Maybe you wanted this, which will preserve the original value in that situation:
cis.InvoiceStatus =
CASE
WHEN RTRIM(LTRIM(imd.[Invoice_PBK])) IS NULL THEN
'HELLO'
WHEN RTRIM(LTRIM(imd.Invoice_DType)) = 'RD' THEN
'233'
ELSE
cis.InvoiceStatus
END
Or maybe you wanted this, to also match an empty string value:
cis.InvoiceStatus =
CASE
WHEN NULLIF(RTRIM(LTRIM(imd.[Invoice_PBK])),'') IS NULL THEN
'HELLO'
WHEN RTRIM(LTRIM(imd.Invoice_DType)) = 'RD' THEN
'233'
END
It's also worth pointing out the two WHEN conditions are looking at two different columns.
Finally, it may be worth a data clean-up project here. Needing to do an LTRIM() will break any chance of using indexes on those fields (RTRIM() is slightly less bad), and index use cuts to the core of database performance.

IsNull with Equal inside of a FROM/JOIN Statement "isNull(t.fieldname,'N') = 'Y'"

Hey guys I'm somewhat new here so I hope I do this properly I apologize if i dont.
Anyway I am trying to understand this isNull operator in SQL. I completely understand the fact that isnull checks if the field in the 1st argument is a Null value then replaces that Null with the second value.
However what does the equal sign outside of the ISNULL operator mean here(= 'Y')?
I don't understand how this equal sign will apply to what I already know about ISNULL(). Btw this isNull statement was in a FROM statement more specifically a JOIN. Any help or insight would be greatly appreciated. The syntax for the ISNULL() is below. Thanks in advance!
isNull(t.fieldname,'N') = 'Y'
That is equivalent to :
(t.fieldname IS NOT NULL AND t.fieldname = 'Y')
However, this would simplify with this also :
t.fieldname = 'Y'
This would filtered only records which has fieldname = 'Y'. This assumes that parts comes from WHERE clause, if not might be for JOIN with ON clause then you can write a simple case expression instead :
ON (CASE WHEN t.FieldName IS NULL THEN 'N' ELSE t.Fieldname END) = 'Y'
ISNULL is a function that simply replaces the NULL values with the specified value, otherwise returns with the original value.
In your case isNull(t.fieldname,'N') returns back with N if the t.fieldname is null
for examples you could check this page: https://www.w3schools.com/sql/sql_isnull.asp
There is a somewhat similar case being discussed here.
IsNull with Equal ¿What does this means?
I hope that it can help you.

SQL Error (4145): An expression of non-boolean type specified in a context where condition is expected, near '('

Using the below statement to check whether a field is null and if it is null then I need to show "Not Yet Approved" message. Otherwise I would like to get a concatenated result of some fields which is mentioned below.
select
iif(isnull(AppByENo1,'true'),'Not Yet Approved',AppByENo1+AppByDesg1+AppByDate1) as result
from myDB
where (E_No = '25')
But getting the above mentioned error while trying to run the sql query.
Please advice where I am making mistake and how to tackle this issue.
try this:
select
iif(isnull(AppByENo1,'true') = 'true','Not Yet Approved',AppByENo1+AppByDesg1+AppByDate1) as result
from myDB
where (E_No = '25')
Use CASE Statement in SELECT clause instead of IFF :
SELECT CASE WHEN ISNULL(AppByENo1,'true') = 'true' THEN 'Not Yet Approved'
ELSE AppByENo1+AppByDesg1+AppByDate1 END as result
FROM myDB WHERE E_No = '25'
Since concatenating null values yields null (providing you're leaving appropiate settings turned on, which you should), you can just use a simple coalesce to replace the null if necessary:
select
COALESCE(AppByENo1+AppByDesg1+AppByDate1,'Not Yet Approved') as result
from myDB
where (E_No = '25')
If you insist on the iif approach, I'd favour:
iif(AppByENo1 is null,'Not Yet Approved',AppByENo1+AppByDesg1+AppByDate1)
E.g. an actual null test, rather than trying to identify a sentinel string that cannot appear naturally and performing a string comparison after isnull.

Oracle : IN and OR

I've a scenrio which process many data in Oracle database. In some cases, the variable Sec_email will contain many values and in some cases Sec_email will contain null or ' '.
so can please any one tell me how to write a query for this?
I tried with
(C.SECONDARY_EMAIL IN ('?,?') OR '' = '' )
where C is the Client table.
When I use this i get the count as 0.
You can perform a not null check before the IN comparison like
Sec_email is not null and C.SECONDARY_EMAIL IN (...
One obvious problem is that Oracle (by default) treats empty strings as NULL. So: '' = '' is the same as NULL = NULL, which is never true.
Arrgh.
In any case, you are probably constructing the query, so use is null instead:
(C.SECONDARY_EMAIL IN ('?,?') OR '' IS NULL
I think the real problem, though, is the first comparison. The IN list has one element with a constant, not two (but perhaps that is your intention). If you want to put a variable number of values for comparison, one method uses regular expressions. For instance:
C.SECONDARY_EMAIL REGEXP_LIKE '^val1|val2|val3$' or '' IS NULL
If you would like to get a list of values when some of them is null you should use:
("some other conditions" OR C.SECONDARY_EMAIL IS NULL)
The question is if it is not null and not ' ' value what you are expecting, if it should be some king of
pattern you should use regular expression:
regexp_like(C.SECONDARY_EMAIL, '^(.+?[,]+?)+$')
Also, if you have a few conditions in where clause use should use brackets to group you conditions null check and another one.
All conditions i this case will be divided by OR.
(C.SECONDARY_EMAIL IS NULL OR regexp_like(C.SECONDARY_EMAIL, '^(.+?[,]+?)+$'))
or
(C.SECONDARY_EMAIL IS NULL OR regexp_like(C.SECONDARY_EMAIL, '^(.+?[,]+?)+$')
OR C.SECONDARY_EMAIL = ' ')

Sql Server: CASE Statement does unexpected behavior when comparing to NULL

Given:
The following Select statement:
select case NULL
when NULL then 0
else 1
end
Problem:
I'm expecting this to return 0 but instead it returns 1. What gives?
Generally speaking, NULL is not something you should attempt to compare for equality, which is what a case statement does. You can use "Is NULL" to test for it. There is no expectation that NULL != NULL or that NULL = NULL. It's an indeterminate, undefined value, not a hard constant.
-- To encompass questions in the comments --
If you need to retrieve a value when you may encounter a NULL column, try this instead:
Case
When SomeColumn IS NULL
Then 0
Else 1
End
I believe that should work. As far as your original post is concerned:
Select Case NULL
When NULL then 0 // Checks for NULL = NULL
else 1 // NULL = NULL is not true (technically, undefined), else happens
end
The trouble is that your Case select automatically attempts to use equality operations. That simply doesn't work with NULL.
I was going to add this as a comment to Aaron's answer, but it was getting too long, so I'll add it as another (part of the) answer.
The CASE statement actually has two distinct modes, simple and searched.
From BOL:
The CASE expression has two formats:
The simple CASE expression compares an expression to a set of simple expressions to determine the result.
The searched CASE expression evaluates a set of Boolean expressions to determine the result.
When the simple CASE (your example) does what it describes as comparison it does an equality comparison - i.e. =
This is clarified in the later documentation:
The simple CASE expression operates by comparing the first expression
to the expression in each WHEN clause for equivalency. If these
expressions are equivalent, the expression in the THEN clause will be
returned.
Allows only an equality check.
Because anything = NULL is always false in ANSI SQL (and if you didn't know this, you need to read up on NULLs in SQL more generally, particularly also with the behavior in the other searched comparison - WHERE x IN (a, b, c)), you cannot use NULL in a simple case and have it ever be compared to a value, with a NULL either in the initial expression or in the list of expressions to be compared against.
If you want to check for NULL, you will have to use an IF/ELSE construct or the searched CASE with a full expression.
I agree that it's kind of unfortunate there is no version which supports an IS comparison to make it easier to write:
select case colname
when IS NULL then 0
else 1
end
Which would make writing certain long CASE statements easier:
select case colname
when IS NULL then ''
when 1 then 'a'
when 2 then 'b'
when 3 then 'c'
when 4 then 'd'
else 'z'
end
But that's just wishful thinking...
An option is to use ISNULL or COALESCE:
select case COALESCE(colname, 999999) -- 999999 is some value never used
when 999999 then ''
when 1 then 'a'
when 2 then 'b'
when 3 then 'c'
when 4 then 'd'
else 'z'
end
But it isn't always a great option.
In addition to the other answers, you need to change the syntax for CASE slightly to do this:
SELECT CASE
WHEN NULL IS NULL THEN 0
ELSE 1
END;
Using the value in your syntax implicitly uses an equals comparison. NULL is unknown, and so is NULL = NULL, so with your current code you will always get zero 1 (geez I did it too).
To get the behavior you want, you can use SET ANSI_NULLS ON; however note that this can change other code in ways you may not be able to predict, and the setting is deprecated - so it will stop working at all in a future version of SQL Server (see this SQL Server 2008 doc).
You need to use the IS NULL operator. Standard comparison operators do not work with NULL.
Check out these MSDN articles about Null that may be useful:
IS [NOT] NULL (Transact-SQL)
Null Values