SQL Server : CASE does not work - sql

SELECT
a.componentId, a.uniqueCode,
'sd'= CASE
WHEN RTRIM(LTRIM(b.name)) IS NULL OR RTRIM(LTRIM(b.uniqueCode)) IS NULL
THEN isnull(b.uniqueCode,'')+isnull(b.name,'')
WHEN RTRIM(LTRIM(b.name)) IS NULL AND RTRIM(LTRIM(b.uniqueCode)) IS NULL
THEN isnull(b.uniqueCode,'')+isnull(b.name,'')
ELSE b.uniqueCode + '(' + (b.name) + ')'
END,
a.specialization
FROM Doctors a
LEFT OUTER JOIN Territories b ON a.locationId = b.componentId;
Suppose b.uniqueCode = T003 and b.name = Dhanmondi 01, then sd should be T003(Dhanmondi 01).
Now if b.name = NULL then sd should be T003, but my query result shows T003().
What is wrong my T-SQL query?

Are you sure that b.name is null? If it has an empty string instead of null you would have the result you see. BTW, the rtrim/ltrim stuff is totally unnecessary when checking with is null and your second when will never happen because you will always end up in the first when if either column is null.
This will treat empty strings as null:
SELECT a.componentId, a.uniqueCode, 'sd'=
CASE
WHEN nullif(b.name, '') IS NULL OR nullif(b.uniqueCode, '') IS NULL
THEN isnull(b.uniqueCode,'')+isnull(b.name,'')
ELSE b.uniqueCode + '(' + (b.name) + ')'
END , a.specialization
FROM Doctors a LEFT OUTER JOIN Territories b ON a.locationId = b.componentId;

Let's sort some basics out first...
Your second WHEN is impossible to reach, since the earlier WHEN will always be true (either null) before the second WHEN (both null).
RTRIM() and LTRIM() will only return NULL if the argument is NULL, so these two condition expressions are identical:
RTRIM(LTRIM(b.name)) IS NULL
b.name IS NULL
Removing redundant code, including the unreachable WHEN, will let you simplify your code considerably:
CASE
WHEN b.name IS NULL OR b.uniqueCode IS NULL
THEN isnull(b.uniqueCode,'') + isnull(b.name,'')
ELSE b.uniqueCode + '(' + b.name + ')'
END
Now that we can read it...
The most likely explanation is that b.name is blank, not NULL.

In SQL and all of the popular SQL products - except Oracle - a NULL and an empty string '' are two different things. So, you should be checking both options:
SELECT a.componentId, a.uniqueCode,
CASE
WHEN b.name IS NULL OR b.name = ''
THEN COALESCE(b.uniqueCode, '')
WHEN b.uniqueCode IS NULL OR b.uniqueCode = ''
THEN b.name
ELSE b.uniqueCode + '(' + b.name + ')'
END AS sd
, a.specialization
...
or to remove leading and trailing spaces:
CASE
WHEN b.name IS NULL OR RTRIM(LTRIM(b.name)) = ''
THEN COALESCE(RTRIM(LTRIM(b.uniqueCode)), '')
WHEN b.uniqueCode IS NULL OR RTRIM(LTRIM(b.uniqueCode)) = ''
THEN RTRIM(LTRIM(b.name))
ELSE RTRIM(LTRIM(b.uniqueCode)) + '('
+ RTRIM(LTRIM(b.name)) + ')'
END AS sd

Related

error- Each column has to have a unique name when you’re returning the query

I am trying to run reporting services with below SQL query
select ca.callingpartynumber, ca.originalcalledpartynumber, case
when calledpartylastname is not null then ca.calledpartylastname + ',' + calledpartyfirstname
else p1.name end,
p1.location, p1.dept, p1.title,
case
when callingpartylastname is not null then ca.callingpartylastname + ',' + callingpartyfirstname
else p3.name end
from calldata.calldetailreport ca
join ps_bc_peoplesource_base p1 on ca.originalcalledpartynumber = replace(p1.bc_int_phone, '-', '')
left outer join ps_bc_peoplesource_base p3 on ca.callingpartynumber = replace(p1.bc_int_phone, '-', '')
where originalcalledpartynumber in (select replace(bc_int_phone, '-', '') internal_modified from ps_bc_peoplesource_base where bc_lan_id = 'f7c')
--and datetimedisconnect between #startdate and #enddate --1221
I get this error-
“An item with the same key has already been added.”
You are missing Column Alias for Two Case Statement in Your SELECT query. As SSRS uses only the column name as the key, not table + column, so it was choking.
Refer Here And Here And Here also
SELECT ca.callingpartynumber, ca.originalcalledpartynumber,
CASE WHEN calledpartylastname IS NOT NULL
THEN ca.calledpartylastname + ',' + calledpartyfirstname
ELSE p1.name END AS calledpartylastname,
p1.location,
p1.dept,
p1.title,
CASE WHEN callingpartylastname IS NOT NULL
THEN ca.callingpartylastname + ',' + callingpartyfirstname
ELSE p3.name END AS callingpartylastname
...
...

How to remove first and last charcter if character is ',' of name in Sql query

I combine two column value with ',' using below query.
SELECT
RTRIM(LTRIM(REPLACE(
IsNull(tbl1 .Reason,'') + ',' + IsNull(tbl2.OtherReason,''),',' ,'')))
FROM tbl1
LEFT JOIN tbl2 ON tbl2.OtherReasonId = tbl1.ReasonId
Now issue is that it remove all ',' using above query and I want to just remove last and first ','.
I have combine two column. Now
if tbl1 .Reason is null then it display output as " ,tbl2.OtherReason " and if tbl2.OtherReason is null the output is "tbl1 .Reason,"
Before above query, I also try with below query:
SELECT
IsNull(tbl1.Reason,'') + ',' + IsNull(tbl2.OtherReason,'')
FROM tbl1
LEFT JOIN tbl2 ON tbl2.OtherReasonId = tbl1.ReasonId
Thanks,
HItesh
You can use a case in the middle to check if the values are null or not.
declare #a nvarchar(5)
,#b nvarchar(5)
set #a = 'abc'
set #b = null--'123'
select isnull(#a, '') + case when #a is not null and #b is not null then ',' else '' end + isnull(#b, '')
Try this:
SELECT
CASE
WHEN tbl1.Reason IS NULL
THEN
CASE
WHEN tbl2.Reason IS NULL
THEN ''
ELSE LTRIM(RTRIM(tb2.Reason))
END
ELSE tbl1.Reason +
CASE
WHEN tbl2.Reason IS NULL
THEN ''
ELSE ',' + LTRIM(RTRIM(tb2.Reason))
END
END
FROM tbl1
LEFT JOIN tbl2 ON tbl2.OtherReasonId = tbl1.ReasonId
You can concatenate a comma to the first value in case that second value is not null :
SELECT
IsNull(tbl1.Reason + case when tbl2.OtherReason is null then '' else ',' end, '') +
IsNull(tbl2.OtherReason,'')
FROM tbl1
LEFT JOIN tbl2 ON tbl2.OtherReasonId = tbl1.ReasonId

Case within Case when combining multiple columns into one

I'm trying to create a query that will take multiple columns in a View and bring it into one column in the query. The values from each column needs to be separated by '|' (pipe).
I've tried:
1) (expression1 + '|' + expression2) AS xxxx, but if one expression has a null value, it makes the results 'null'.
2) CAST (expression1 as varchar (10)) + '|' + CAST (expression2 as varchar (10)) AS xxxx, but get the same results.
3) CASE (expression1 is null) then (' ') else (expression1) +'|' + CASE (expression2 is null) then (' ') else (expression2) END AS xxxx, but I get a syntax error near the keyword 'AS'.
Here's the full query using CASE.
SELECT DISTINCT dbo.REG.BUILDING, dbo.REG.CURRENT_STATUS, dbo.REG_CONTACT.LOGIN_ID, dbo.REG.LAST_NAME
, CASE WHEN dbo.View_MYAccess_Period1.CRSGRP1 is null then ' ' else dbo.View_MYAccess_Period1.CRSGRP1 + ' |' +
CASE WHEN dbo.View_MYAccess_Period2.CRSGRP2 is null then ' ' else dbo.View_MYAccess_Period2.CRSGRP2
END AS CRSGRP
FROM dbo.REG_CONTACT RIGHT OUTER JOIN
dbo.REG_STU_CONTACT ON dbo.REG_CONTACT.CONTACT_ID = dbo.REG_STU_CONTACT.CONTACT_ID RIGHT OUTER JOIN
dbo.REG ON dbo.REG_STU_CONTACT.STUDENT_ID = dbo.REG.STUDENT_ID LEFT OUTER JOIN
dbo.View_MYAccess_Period1 ON dbo.REG.STUDENT_ID = dbo.View_MYAccess_Period1.STUDENT_ID LEFT OUTER JOIN
dbo.View_MYAccess_Period2 ON dbo.REG.STUDENT_ID = dbo.View_MYAccess_Period2.STUDENT_ID
Any help for this newbie would be greatly appreciated!
Use ISNULL function,
SELECT DISTINCT dbo.REG.BUILDING, dbo.REG.CURRENT_STATUS, dbo.REG_CONTACT.LOGIN_ID, dbo.REG.LAST_NAME
, ISNULL(dbo.View_MYAccess_Period1.CRSGRP1,' ') + ' |' +
ISNULL(dbo.View_MYAccess_Period2.CRSGRP2,' ') CRSGRP
FROM dbo.REG_CONTACT RIGHT OUTER JOIN
dbo.REG_STU_CONTACT ON dbo.REG_CONTACT.CONTACT_ID = dbo.REG_STU_CONTACT.CONTACT_ID RIGHT OUTER JOIN
dbo.REG ON dbo.REG_STU_CONTACT.STUDENT_ID = dbo.REG.STUDENT_ID LEFT OUTER JOIN
dbo.View_MYAccess_Period1 ON dbo.REG.STUDENT_ID = dbo.View_MYAccess_Period1.STUDENT_ID LEFT OUTER JOIN
dbo.View_MYAccess_Period2 ON dbo.REG.STUDENT_ID = dbo.View_MYAccess_Period2.STUDENT_ID
In example 1, you might use the COALESCE(expression, fallback) function to force expression to return a fallback value if the expression is null. (Then tweak the rest of the logic accordingly.)
In your example 3, you need another END keyword:
CASE
(expression1 is null) then (' ')
ELSE (expression1) +'|' +
CASE (expression2 is null) then (' ') else (expression2) END
END AS xxxx

Character set mismatch

I have a SQL statement like this:
SELECT
a.ColumnA, b.ColumnB ||
CASE WHEN TRIM(c.ColumnC) IS NOT NULL THEN ' (' || c.ColumnC || ')' ELSE '' END AS ClassName
FROM TableA a INNER JOIN TableB b ON a.SomeColumn = b.SomeColumn
INNER JOIN TableC c on a.SomeCol = c.SomeCol
I'm getting an error "Character set mismatch" at the " ELSE '' " part of the CASE expression.
Can someone suggest where I'm doing it wrong? Thank you.
You cannot concatenate VARCHAR and NVARCHAR values without a CAST statement.
CASE WHEN TRIM(c.ColumnC) IS NOT NULL
THEN ' (' || c.ColumnC || ')'
ELSE N'' END A
is a more concise solution. N'' gives you a unicode empty string
Did you try replacing '' with NULL?
Also, try removing ELSE part altogether because it will return NULL anyway.
Just erase the ELSE, would make your code easier to read

Conditionals in transact-sql select column lists

I've got a query that looks a bit like this:
select
records.id,
contacts.name + ' (' + contacts.organization + ')' as contact,
from records
left join contacts on records.contact = contacts.contactid
Problem is - contacts.organization is frequently empty, and I get contacts like "John Smith ()". Is there a way to only concatenate the organization if it's non-empty?
Use a CASE statement
SELECT
records.id,
CASE contacts.organization
WHEN '' THEN contacts.name
ELSE contacts.name + ' (' + contacts.organization + ')'
END as Contact
FROM records
LEFT JOIN contacts ON records.contact = contacts.contactid
You could modify it to also check for NULL values, but I do not believe you have that issue because if you had a NULL in your contacts.organization, your entire result field would be null instead of blank.
Not sure if this is the best way to do it:
CASE contacts.organization
WHEN '' THEN ''
ELSE '(' + contacts.organzation + ')' END
use a CASE, like CASE WHEN contacts.organization not null then ' (' + c.o + ') ' else '' end
You always need to expect nulls, because of your outer join:
select
records.id,
contacts.name + CASE WHEN contacts.organization IS NULL OR contacts.organization='' THEN '' ELSE ' (' + contacts.organization + ')' END as contact,
from records
left join contacts on records.contact = contacts.contactid
If you're dealing with NULL values there are some functions that specialize in them which are worth knowing.
ISNULL()
COALESCE()
NULLIF()
NULLIF() might be the one you're looking for. It basically takes two params. It returns the first param unless it is NULL, otherwise it returns the second.
Here's what I approximate your code would be:
select
records.id,
contacts.name + ISNULL(' (' + contacts.organization + ')', '') as contact,
from records
left join contacts on records.contact = contacts.contactid
Most NULL-related functions can be replaced by a larger CASE statement. CASE is your more general tool. But using specific functions will make your code cleaner, or at least more terse.