Conditionals in transact-sql select column lists - sql

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.

Related

How to do not null check on LEFT function on the select query

I have a query that returns some demographics like firstName, lastName, MiddleName and i need to use LEFT function on each to filter the First Letter of each column like LEFt(firstName, 1).This is working fine when each column is not a null value. when it is null value
select otherColumns, LEFT(sub.LastName, 1) + ',' + LEFT(sub.FirstName, 1) + ' ' + LEFT(sub.MiddleName, 1) as patientInitials from <table> <inner joins> <some where conditions>;
But when one of demographics like middleName is null and other firstName, lastName are not null , patientInitials are evaulating to NULL, not sure why?
I resolved my issue by adding COALESCE
LEFT(sub.LastName, 1) + ',' + LEFT(sub.FirstName, 1) + ' ' + COALESCE((LEFT(sub.MiddleName, 1)),'') as patientInitials
But is there any other good way to check for notNull on the LEFT function ??
Help Appreciated!
But is there any other good way to check for notNull on the LEFT function ??
CONCAT function ignores NULLs:
SELECT CONCAT(LEFT(sub.LastName, 1), ',' ,
LEFT(sub.FirstName, 1),
' ' + LEFT(sub.MiddleName, 1)) patientInitials
FROM tab;
' ' + LEFT(sub.MiddleName, 1)) using ' ' will remove leading space in case if Middle Name is NULL.
The CONCAT_WS function also has a similar function:CONCAT_WS (Transact-SQL)

sql concatenation with blank cells

So I am extracting data from one table to another
SELECT *
LTRIM(ADRESSE + ',' + ADRESSE2) AS ADDRESS12
FROM [Homestore].[dbo].[CLIENT]
Issue is that if the cells are blank i still get a comma ,
I have tried using & instead of + but nvarchar is incompatible in the '&' operator. Any ideas how I only insert the comma if there is something to concatenate?
You want the equivalent of CONCAT_WS() in other databases. You can do this with STUFF() and some string logic in SQL Server:
SELECT c.*
STUFF( (COALESCE(',' + ADRESSE, '') +
COALESCE(',' + ADRESSE2, '') +
), 1, 1, ''
) AS ADDRESS12
FROM [Homestore].[dbo].[CLIENT] c;
This structure is convenient, because you can just add more COALESCE() expressions for more columns.
use case expression
SELECT *, LTRIM(ADRESSE + case when ADRESSE is not null then ',' end + ADRESSE2) AS ADDRESS12
FROM [Homestore].[dbo].[CLIENT]
use case when for null checking
SELECT *
LTRIM(ADRESSE + case when ADRESSE2 is not null then
',' else '' end + ADRESSE2) AS ADDRESS12
FROM [Homestore].[dbo].[CLIENT]

some weird signs appearing on SQL SERVER Query output

i have written a SELECT Query on SQL SERVER 2014 . I have got the desired output . but an apostrophe symbol(') appearing on 'TaskAction' field data(at the end of each data). here it is my script:
SELECT
WOtask.PK,
WOPK,
TaskNo,
TaskAction =
CASE
WHEN WOTask.AssetPK IS NOT NULL THEN '<b>' + Asset.AssetName + ' [' + Asset.AssetID + ']</b> ' + CASE
WHEN Asset.Vicinity IS NOT NULL AND
Asset.Vicinity <> '''' THEN RTRIM(Asset.Vicinity) + ': '
ELSE ''''
END + WOtask.TaskAction + CASE
WHEN CONVERT(varchar, ValueLow) IS NOT NULL AND
CONVERT(varchar, ValueHi) IS NOT NULL AND
Spec = 1 THEN ' (Range: '' + CONVERT(VARCHAR,CONVERT(FLOAT,ISNULL(ValueLow,0))) + '' - '' + CONVERT(VARCHAR,CONVERT(FLOAT,ISNULL(ValueHi,0))) + )'
ELSE ''''
END
ELSE WOtask.TaskAction + CASE
WHEN CONVERT(varchar, ValueLow) IS NOT NULL AND
CONVERT(varchar, ValueHi) IS NOT NULL AND
Spec = 1 THEN ' (Range: '' + CONVERT(VARCHAR,CONVERT(FLOAT,ISNULL(ValueLow,0))) + '' - '' + CONVERT(VARCHAR,CONVERT(FLOAT,ISNULL(ValueHi,0))) + )'
ELSE ''''
END
END,
Rate,
Measurement,
Initials,
Fail,
Complete,
Header,
LineStyle,
WOtask.Comments,
WOtask.NotApplicable,
WOTask.Photo1,
WOTask.Photo2
FROM WOtask WITH (NOLOCK)
LEFT OUTER JOIN Asset WITH (NOLOCK)
ON Asset.AssetPK = WOTask.AssetPK
LEFT OUTER JOIN AssetSpecification
ON AssetSpecification.PK = WOTask.AssetSpecificationPK
WHERE (WOPK IN (SELECT
WOPK
FROM WO WITH (NOLOCK)
LEFT OUTER JOIN Asset WITH (NOLOCK)
ON Asset.AssetPK = WO.AssetPK
LEFT OUTER JOIN AssetHierarchy WITH (NOLOCK)
ON AssetHierarchy.AssetPK = WO.AssetPK
WHERE WO.WOPK = 10109)
)
ORDER BY WOPK, TaskNo
now please check my output and error
please help to solve this issue. Thanks in Advance.
As noted in comments, use ELSE '' instead of ELSE ''''. The reason is that within a pair of single quotes, then '' tells SQL to escape a single quote into your output.
For instance, to show the output User's, you would need SELECT 'User''s'.

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

SQL Server : CASE does not work

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