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
Related
I wrote a SQL to query table mat from an oracle db where column A is not null. Column A is varchar and its default value is ' '. I wrote the sql below:
select * from mat where matnr='test' and A <>'' and A <> ' '
But it return an empty data set.
Then I ran:
select * from mat where matnr='test' and A <> ' '
This query worked. So what is the reason? Thx.
In Oracle, '' means NULL. Any direct comparison to NULL returns NULL instead of TRUE or FALSE, so you cannot say A <> '' - you must say A IS NOT NULL.
Another possibility would be to use the NVL function, replacing NULL with ' ', so that you could say
select * from mat where matnr='test' and NVL(A, ' ') <> ' '
I had a query like:
SELECT ISNULL(S.Name+'.'+T.Name,'Table Not Found')
FROM DataProfile.Tables T
INNER JOIN DataProfile.Schemas S ON T.schemaId=S.Id
WHERE S.Name+'.'+T.Name=#TableName
Then I tried
IIF(LEN(S.Name+'.'+T.Name)>0,S.Name+'.'+T.Name,NULL)
But when it doesn't find the named table returns not output, Value or Null value or anything I can work on.
This is going to be used as a crosscheck.
Does anybody have any idea?
Thanks for those who payed attention to what I exactly asked and for their responses.
Here the way I tried:
DECLARE #Check NVARCHAR(MAX) = 'TABLE DOES NOT FOUND'
SELECT #Check= S.Name + '.' + T.Name
FROM DataProfile.Tables T
INNER JOIN DataProfile.Schemas S ON T.schemaId=S.Id
WHERE S.Name+'.'+T.Name=#TableName
SELECT #CHECK
And That Worked for me
this will always return a row:
select v.TableName, ISNULL(found.result, 'not found') result
from (values(#TableName))v(TableName)
outer apply (
select CAST('found' as nvarchar(11)) result
from DataProfile.Tables T
join DataProfile.Schemas S ON T.schemaId=S.Id
where S.Name+'.'+T.Name=v.TableName
)found
you should try this
SELECT CASE WHEN (LEN(S.Name + '.' + T.Name))> 1 THEN S.Name + '.' + T.Name ELSE NULL END
So you qry will look like
SELECT CASE
WHEN (LEN(S.Name + '.' + T.Name))> 1 THEN
S.Name + '.' + T.Name
ELSE
NULL -- Here use any expresion which you want
END
FROM DataProfile.Tables T
INNER JOIN DataProfile.Schemas S ON T.schemaId=S.Id
WHERE S.Name+'.'+T.Name=#TableName
Here you are using ISNULL(S.Name+'.'+T.Name,'Table Not Found') which never return false part due to if S.Name and T.Name both are null then still that value will be '.'
Try doing it this way:
with table_qry as
(
select S.Name as SName, T.Name as TName
from DataProfile.Tables T
inner join DataProfile.Schemas S
on T.SchemaId = S.Id
where S.Name+'.'+T.Name = #TableName
)
select case when (select count(1) from table_qry) > 0 then
SName+'.'+TName else 'Table Not Found' end as TableName
from table_qry;
There are more elegant ways of doing it, but this should work just fine for you.
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
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
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.