SELECT CASE
WHEN vGlTransType = 'R' THEN tkt_seq_num
WHEN vGlTransType in ('A','E','X') then
break
END
there is no loop in CASE
use
ELSE null
before END to return a null value when other conditions are not satisfied
Like alex mentioned, you want ELSE:
SELECT CASE WHEN vGlTransType = 'R' THEN tkt_seq_num
ELSE NULL
END
ELSE NULL is default btw, that means you could just skip it:
SELECT CASE WHEN vGlTransType = 'R' THEN tkt_seq_num
END
You got a lot of negative responses because you use the wrong vocabulary. Let me quote a article I wrote on CASE:
SQL is a declarative language: it does not provide control over
program flow like if does for imperative programs. Nevertheless, SQL
has something similar: the case expression. Being an expression—rather
than a control structure—means that case varies the result of formulas
(expressions) based on conditions. Its use is similar to the ternary
operator ?: in other programming languages.
Your question suggest that you think SQL's CASE is similar to C's SWITCH (plus CASE). But it isn't.
Related
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.
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.
I have a situation in which I need to do nothing if these conditions are met in the when part and assign value otherwise. I am using the case when <expression> then <some operation/assignment> end in my SQL.
I want to skip this then part as this is a special condition and I do not want any assignment here just pass by to the else
(case
when '$usertype_id' = 'null' or '$usertype_id' = 0 or '$usertype_id' = 999
then //do nothing
else x.usertype_id = '$usertype_id'
end)
Please let me know how can I achieve this. Thank you.
You don't. You use conditional logic without a case expression:
('$usertype_id = 'null' or '$usertype_id = 0 or '$usertype_id = 999) or
(x.usertype_id = '$usertype_id')
More importantly, I would strongly, strongly encourage you to use parameters instead of munging query strings with parameter values.
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.
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