SQL : IF ELSE with THEN of SELECT CASE - sql

I am sorry if this duplicate question. Please let me know where I can find right question. I have a stored procedure where I can just make few minor modifications and I cannot change/update data in my Student table. We have this problem and I need to fix it.
In below statement, sometimes student.FullName will have [NEXTLINE] in it then I need to replace it with '' ( empty string) else nothing return as it is. I tried various ways but getting error when I replace +student.FullName in THEN clause. Please let me know how can I do this.
CASE
WHEN student.ID IS NULL THEN
CASE
WHEN student.Status = 0 THEN '<BOLDSTART>rejected<BOLDEND>.'+'[LINEBREAK]'+ student.FullName
WHEN student.Status = 1 THEN ' <BOLDSTART>accepted<BOLDEND>.'
END
END
I want to add similar logic like below in above +student.FullName
IF (student.FullName LIKE '%[NEXTLINE]%')
BEGIN
SELECT REPLACE (student.FullName,'[NEXTLINE]','')
END
ELSE
SELECT student.FullName
Thanks in advance
UPDATE
Thanks to D Stanley. I solved my problem like below
CASE
WHEN student.ID IS NULL THEN
WHEN student.Status = 0 THEN '<BOLDSTART>rejected<BOLDEND>.' + '[LINEBREAK]' + REPLACE (student.FullName,'[NEXTLINE]','')
WHEN student.Status = 1 THEN ' <BOLDSTART>accepted<BOLDEND>.'
END

You can just wrap your entire logic in a replace() call:
REPLACE((CASE WHEN student.ID IS NOT NULL THEN NULL
WHEN student.Status = 0
THEN '<BOLDSTART>rejected<BOLDEND>.' + '[LINEBREAK]' + student.FullName
WHEN student.Status = 1
THEN ' <BOLDSTART>accepted<BOLDEND>.'
END), '[NEXTLINE]', ''
)
Notice that I also simplified your logic. The nested case statements are not necessary. case is evaluated sequentially, so you can just check for the conditions you want.

Is this what you want?
replace
+ student.FullName
for
+ CASE
WHEN student.FullName LIKE '%[NEXTLINE]%' THEN REPLACE (student.FullName,'[NEXTLINE]','')
ELSE student.FullName
END

You don't need to see if it contains the string. If it does not, REPLACE will just return the original string:
CASE
WHEN student.ID IS NULL THEN
CASE
WHEN student.Status = 0 THEN
'<BOLDSTART>rejected<BOLDEND>.'+'[LINEBREAK]'+ REPLACE(student.FullName,'[NEXTLINE]','')
WHEN student.Status = 1 THEN
' <BOLDSTART>accepted<BOLDEND>.'
END
END

Related

Problem with field not equal to null in case statement

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 ''

Does the SQL'%' wild card character capture null values?

Recently I've come across a problem with a query that isn't returning everything that it's expected to return. Part of the query which selects by a condition is as follows:
AND field LIKE
CASE WHEN #val = 1 THEN
'%'
ELSE
'N'
END
Now, when #val is 1, I'd expect this piece of code to essentially do nothing, as in the condition to basically accept any value what so ever, including null values.
Am I wrong about this? And if so, does anyone have a solution? I was thinking something along the lines of
AND field LIKE
CASE WHEN #val = 1 THEN
'%' OR ISNULL(field)
ELSE
'N'
END
However SQL doesn't work like that, but that's basically what I wish to accomplish.
Thanks all, and sorry if this is a duplicate, I couldn't find an answer.
Based on what you're trying to accomplish, it seems your query could be optimized to this:
AND (#val = 1 OR field = 'N')
There doesn't seem to be a reason for the LIKE.
UPDATE
Since you are trying to understand the behavior of LIKE and CASE moreso than working with existing queries, here are some variations of the accepted answer.
To use CASE within the LIKE, you have to use something like COALESCE to handle the null case as well.
COALESCE(Field, '') LIKE (CASE WHEN #val = 1 THEN '%' ELSE 'N' END)
Otherwise, you can use the LIKE within the CASE (like accepted answer), but probably personal preference that this seems easier to read:
1 = (CASE WHEN #val = 1 OR Field LIKE 'N' THEN 1 ELSE 0 END)
field LIKE '%' does not match null. CASE expressions must return a single type of result, I like int in most of mine.
AND 1 = CASE
WHEN #val = 1 THEN 1
WHEN field like 'N' THEN 1
ELSE 0
END
Try this (assuming that field is varchar or nvarchar) -
AND ISNULL(field,'') LIKE
CASE WHEN #val = 1 THEN
'%'
ELSE
'N'
END

Using a CASE function

I am using Oracle and am trying to build out some sql for the following scenario:
On EMPLOYEES table, if employee has ADDRESS3 not equal to ' ', populate this field with ADDRESS2 else, populate this field with ADDRESS1.
...
, ADDRESS_LINE2 = NVL((
SELECT (CASE t2.ADDRESS3 != ' ' THEN t2.ADDRESS2 ELSE t2.ADDRESS1 END)
FROM EMPLOYEES t2
WHERE t2.EMPLID = PS_Z_EXS_EMP_TBL_T.EMPLID
), t2.ADDRESS1)
...
but it keeps giving me an error message about missing the right parenthesis. When I comment this bit out though it runs fine. DOes anyone know what I'm doing wrong?
CASE has two variants - both needs WHEN clauses.
One variant can have complete and complex boolean expression in each WHEN clause:
CASE
WHEN t2.ADDRESS3 != ' ' THEN t2.ADDRESS2
ELSE t2.ADDRESS1
END
In the other variant each WHEN clause contain values to be tested for the CASE expression:
CASE t2.ADDRESS3
WHEN ' ' THEN t2.ADDRESS1
ELSE t2.ADDRESS2
END
The last one cannot do != so therefore "reversed" logic ;-)
You need the END keyword at the end of a case expression:
CASE t2.ADDRESS3 != ' ' THEN t2.ADDRESS2 ELSE t2.ADDRESS1 END

Looking for an alternative to messy SQL ISNULL/NULLIF

I have a SQL query running on SQL Server 2012 that needs to compare a bit value and return a string if that value is 1 and an empty string if it is zero.
Originally I had it as a CASE statement like this:
CASE WHEN myBit = 0 THEN
-- do other comparisons etc to build up the return string.
+'myString'
ELSE
-- do other comparisons etc to build up the return string.
'' END
The problem is that all of the code in 'do other' section is the same. All I want to do is append a string to the returned value if the bit is zero and nothing if it is 1.
So I refactored it to only have the common code once and then append to the string at the end like this:
-- do other comparisons etc to build up the return string. +
ISNULL(NULLIF(Cast(ISNULL(CAST(NULLIF(myBit, 0) AS NVARCHAR), 'myString') AS varchar),'0'),'')
However the above seems very messy not least because of the CAST statements required.
I'm looking for a clean and neat way of doing this but have run out of ideas - anyone have a better way of achieving this? Thanks.
Just add your CASE statement inline. Don't forget to return an empty string when mybit=1, or the whole thing will return NULL.
Select
-- do other comparisons etc to build up the return string.
+ Case When #mybit=0 Then mystring else '' End
You can also use IIF and CONCAT as you are on SQL Server 2012.
SELECT CONCAT('Start',
IIF(#mybit=0,'myString',''),
'End')
IIF is a bit more concise than CASE. CONCAT might be beneficial in that it casts non string types to strings automatically and concatenating NULL is treated the same as concatenating an empty string.
Also you can use a simple case here as;
Select 'Your other string ' +
Case mybit When 0 then 'mystring' else '' End As Results
--Results will be like
mybit Results
0 'Your other string mystring'
1 'Your other string '
OR if you want nothing (null) to return if mybit <> 0 then use a simple case without else part as;
Select 'Your other string ' + Case mybit When 0 then 'mystring' End As Results
--Results will be like
mybit Results
0 'Your other string mystring'
1 null
SQL-SERVER-DEMO for both cases
Can you put the common code into a subquery? It would resemble this:
select case when myBit = 0 then value else value + 'what you append' end returnvalue
from
(subquery with common code) abc
Or maybe a function
select case when myBit = 0 then yourfunction()
else yourfunction + 'what you append' end returnvalue

TSQL CASE LTRIM (RTRIM NULL

SQL Syntax is still something I am learning. I am getting the error noted below the this snippet of code.
SELECT
CASE WHEN LTRIM(RTRIM(cLehmanNo)) =' ' THEN NULL
WHEN cLehmanNo IS NOT NULL THEN REPLACE ( cLehmanNo,SUBSTRING (cLehmanNo,PATINDEX( '%[^a-zA-Z0-9 '''''']%',cLehmanNo),1), ' ' )
END asLOAN_NUMBER
,CASE WHEN LTRIM(RTRIM(cMERS)) =' ' THEN NULL
WHEN cMERS IS NOT NULL THEN REPLACE ( cMERS,SUBSTRING (cMERS,PATINDEX( '%[^a-zA-Z0-9 '''''']%',cMERS),1), ' ' )
END asMERS_ID
and 100+ more of same.
Msg 8133, Level 16, State 1, Line 1
None of the result expressions in a CASE specification can be NULL.
What am I doing wrong? How do I keep the gist of the statement and not get this crazy error?
This happens when it can't infer the type.
e.g.
SELECT CASE WHEN 1 = 2 THEN NULL ELSE NULL END
But this works
SELECT CASE WHEN 1 = 2 THEN NULL ELSE replace(NULL,'','') END
so I doubt the error is from the code you have shown us (You are using string functions and the following quick test shows that it will assume that to be varchar(8000))
SELECT CASE WHEN 1 = 2 THEN NULL ELSE REPLACE(NULL,'','') END a
INTO t /*Creates column of datatype varchar(8000)*/
You need to convert NULL to a correct type matching the overall values, e.g. CONVERT(VARCHAR(10), NULL), otherwise the server can't deduce which type to make the resulting value.
The error message actually means that all results in one of your case expressions are null. You have an expression like:
case when something then null when something then null end
At least one of the results has to be something other than null. You could circumvent this, but most likely there is a mistake in the query, as a case exression that always returns the same result is pointless.
The error message has been changed to:
At least one of the result expressions
in a CASE specification must be an
expression other than the NULL
constant.
SELECT
CASE WHEN LTRIM(RTRIM(cLehmanNo)) =' ' THEN NULL
WHEN cLehmanNo IS NOT NULL THEN REPLACE ( cLehmanNo,SUBSTRING (cLehmanNo,PATINDEX( '%[^a-zA-Z0-9 '''''']%',cLehmanNo),1), ' ' )
ELSE ''
END asLOAN_NUMBER
,CASE WHEN LTRIM(RTRIM(cMERS)) =' ' THEN NULL
WHEN cMERS IS NOT NULL THEN REPLACE ( cMERS,SUBSTRING (cMERS,PATINDEX( '%[^a-zA-Z0-9 '''''']%',cMERS),1), ' ' )
ELSE ''
END asMERS_ID