Using IF condition inside CONCAT function of SQL Query - sql

I am trying to implement a concatenation inside a SQL query. I need to use comma as separator between the values.
select concat(technology,',',secondary_technology,',',tertiary_technology) as Technology from deals
This works completely fine. But if there are no values in secondary and tertiary technology columns, the result looks something like
Blue Prism,,
So I need to put a condition if secondary and tertiary technologies are null, then the commas need to be omitted.
I am using the following query:
select concat(technology,if(secondary_technology is null,'',','),secondary_technology,if(tertiary_technology is null,'',','),tertiary_technology) as Technology from deals
But this throws error saying
Incorrect Syntax near the keyword 'if'.
Incorrect Syntax near ','.
Please help me with this!
I am using MS SQL Server 2014
Thank you in advance..

Concat will ignore NULL values when appending. Try this
select CONCAT(technology, ',' +secondary_technology, ',' +tertiary_technology)
from deals
If technology column could be null.
select case when technology is null then stuff(Result, 1, 1, '') else Result end
from (
select technology, CONCAT(technology, ',' +secondary_technology, ',' +tertiary_technology) as Result
from deals
) tab
You might also want to check for Empty string columns using NULLIF.
select case
when coalesce(technology,'') = '' then stuff(Result, 1, 1, '')
else Result
end Result
from
(
select technology
, CONCAT(technology, ',' + nullif(secondary_technology,''), ',' + nullif(tertiary_technology,'')) as Result
from deals
) tab

Use coalesce() :
select concat(technology, coalesce(',' +secondary_technology, ''), coalesce(',' +tertiary_technology, '')) as Technology
from deals;
EDIT : Use stuff() :
select stuff(<concat query> 1,1, '')
from deals;

Please use the below code as alternative:
SELECT CONCAT(technology, ISNULL(secondary_technology,''),ISNULL(tertiary_technology,'')) AS Technology
FROM deals;

try this:
select concat(
technology,
CASE WHEN secondary_technology IS NOT NULL
THEN concat(', ', secondary_technology)
ELSE ''
END,
CASE WHEN tertiary_technology IS NOT NULL
THEN concat(', ', tertiary_technology)
ELSE ''
END,
) as Technology
from deals;
See this answer related to this issue: https://stackoverflow.com/a/19242830/3554534

Related

TRIM forward slash in T-SQL

I have the following code...
TRIM(LEADING '/' FROM ci.Long_description_1) as 'Description',
I am getting the error message
Incorrect syntax near '/'
Whats the best way of writing this?
Thanks
If you are using SQL Server 2017+, you may use TRIM() with a small trick (by default TRIM() removes the specified characters from the start and the end of the string):
SELECT LEFT(
TRIM('/' FROM Long_description_1 + '?'),
LEN(TRIM('/' FROM Long_description_1 + '?')) - 1
) AS Description
FROM (VALUES
(NULL),
('abcd'),
('1234/'),
('////abcd'),
('/folder/subfolder/x.yz')
) ci (Long_description_1)
Result:
Description
----------------------
abcd
1234/
abcd
folder/subfolder/x.yz
I think you want to remove '/' if it is the first character of Long_description_1 column value. TRIM function in SQL Server will not work the way you are expecting.
For this you can write your query like following.
SELECT CASE
WHEN CHARINDEX('/', ci.Long_description_1) = 1
THEN RIGHT(ci.Long_description_1, LEN(ci.Long_description_1) - 1)
ELSE ci.Long_description_1
END AS [Description]
FROM YouTable

how to compare string in SQL without using LIKE

I am using SQL query shown below to compare AMCcode. But if I compare the AMCcode '1' using LIKE operator it will compare all the entries with AMCcode 1, 10,11,12,13. .. 19, 21,31.... etc. But I want to match the AMCcode only with 1. Please suggest how can I do it. The code is given below :
ISNULL(CONVERT(VARCHAR(10),PM.PA_AMCCode), '') like
(
CASE
WHEN #AMCCode IS NULL THEN '%'
ELSE '%'+#AMCCode+ '%'
END
)
This is part of the code where I need to replace the LIKE operator with any other operator which will give the AMCcode with 1 when I want to search AMCcode of 1, not all 10,11,12..... Please help
I think you are looking for something like this:
where ',' + cast(PM.PA_AMCCode as varchar(255)) + ',' like '%,' + #AMCCodes + ',%'
This includes the delimiters in the comparison.
Note that a better method is to split the string and use a join, something like this:
select t.*
from t cross apply
(select cast(code as int) as code
from dbo.split(#AMCCodes, ',') s(code)
) s
where t.AMCCode = s.code;
This is better because under some circumstances, this version can make use of an index on AMCCode.
If you want to exactly match the value, you don't need to use '%' in your query. You can just use like as below
ISNULL(CONVERT(VARCHAR(10),PM.PA_AMCCode), '') like
(
CASE
WHEN #AMCCode IS NULL THEN '%'
ELSE #AMCCode
END
)
Possibly you can remove case statement and query like
ISNULL(CONVERT(VARCHAR(10),PM.PA_AMCCode), '') like #AMCCode

Running SQL query to remove all trailing and beginning double quotes only affects first record in result set

I'm having a problem when running the below query - it seems to ONLY affect the very first record. The query removes all trailing and beginning double quotes. The first query is the one that does this; the second query is just to demonstrate that there are multiple records that have beginning double quotes that I need removed.
QUESTION: As you can see the first record resulting from the top query is fine - it has its double quotes removed from the beginning. But all subsequent queries appear to be untouched. Why?
If quotes are always assumed to exist at both the beginning and the end, adjust your CASE statement to look for instances where both cases exist:
CASE
WHEN ([Message] LIKE '"%' AND [Message] LIKE '%"') THEN LEFT(RIGHT([Message], LEN([Message])-1),LEN([Message]-2)
ELSE [Message]
EDIT
If assumption is not valid, combine above syntax with your existing CASE logic:
CASE
WHEN ([Message] LIKE '"%' AND [Message] LIKE '%"') THEN LEFT(RIGHT([Message],LEN([Message])-1),LEN([Message]-2)
WHEN ([Message] LIKE '"%') THEN RIGHT([Message],LEN([Message]-1)
WHEN ([Message] LIKE '%"') THEN LEFT([Message],LEN([Message]-1)
ELSE [Message]
Because your CASE statement is only evaluating the first condition met, it will only ever remove one of the statements.
Try something like the following:
SELECT REPLACE(SUBSTRING(Message, 1, 1), '"', '') + SUBSTRING(Message, 2, LEN(Message) - 2) + REPLACE(SUBSTRING(Message, LEN(Message), 1), '"', '')
EDIT: As Martin Smith pointed out, my original code wouldn't work if a string was under two characters, so ...
CREATE TABLE #Message (Message VARCHAR(20))
INSERT INTO #Message (Message)
SELECT '"SomeText"'
UNION
SELECT '"SomeText'
UNION
SELECT 'SomeText"'
UNION
SELECT 'S'
SELECT
CASE
WHEN LEN(Message) >=2
THEN REPLACE(SUBSTRING(Message, 1, 1), '"', '') + SUBSTRING(Message, 2, LEN(Message) - 2) + REPLACE(SUBSTRING(Message, LEN(Message), 1), '"', '')
ELSE Message
END AS Message
FROM #Message
DROP TABLE #Message
Try this:
SELECT REPLACE([Message], '"', '') AS [Message] FROM SomeTable

SQL Query - Concatenating Results into One String [duplicate]

This question already has answers here:
How to concatenate text from multiple rows into a single text string in SQL Server
(47 answers)
Closed 7 years ago.
I have a sql function that includes this code:
DECLARE #CodeNameString varchar(100)
SELECT CodeName FROM AccountCodes ORDER BY Sort
I need to concatenate all results from the select query into CodeNameString.
Obviously a FOREACH loop in C# code would do this, but how do I do it in SQL?
If you're on SQL Server 2005 or up, you can use this FOR XML PATH & STUFF trick:
DECLARE #CodeNameString varchar(100)
SELECT
#CodeNameString = STUFF( (SELECT ',' + CodeName
FROM dbo.AccountCodes
ORDER BY Sort
FOR XML PATH('')),
1, 1, '')
The FOR XML PATH('') basically concatenates your strings together into one, long XML result (something like ,code1,code2,code3 etc.) and the STUFF puts a "nothing" character at the first character, e.g. wipes out the "superfluous" first comma, to give you the result you're probably looking for.
UPDATE: OK - I understand the comments - if your text in the database table already contains characters like <, > or &, then my current solution will in fact encode those into <, >, and &.
If you have a problem with that XML encoding - then yes, you must look at the solution proposed by #KM which works for those characters, too. One word of warning from me: this approach is a lot more resource and processing intensive - just so you know.
DECLARE #CodeNameString varchar(max)
SET #CodeNameString=''
SELECT #CodeNameString=#CodeNameString+CodeName FROM AccountCodes ORDER BY Sort
SELECT #CodeNameString
#AlexanderMP's answer is correct, but you can also consider handling nulls with coalesce:
declare #CodeNameString nvarchar(max)
set #CodeNameString = null
SELECT #CodeNameString = Coalesce(#CodeNameString + ', ', '') + cast(CodeName as varchar) from AccountCodes
select #CodeNameString
For SQL Server 2005 and above use Coalesce for nulls and I am using Cast or Convert if there are numeric values -
declare #CodeNameString nvarchar(max)
select #CodeNameString = COALESCE(#CodeNameString + ',', '') + Cast(CodeName as varchar) from AccountCodes ORDER BY Sort
select #CodeNameString
from msdn Do not use a variable in a SELECT statement to concatenate values (that is, to compute aggregate values). Unexpected query results may occur. This is because all expressions in the SELECT list (including assignments) are not guaranteed to be executed exactly once for each output row
The above seems to say that concatenation as done above is not valid as the assignment might be done more times than there are rows returned by the select
Here is another real life example that works fine at least with 2008 release (and later).
This is the original query which uses simple max() to get at least one of the values:
SELECT option_name, Field_M3_name, max(Option_value) AS "Option value", max(Sorting) AS "Sorted"
FROM Value_list group by Option_name, Field_M3_name
ORDER BY option_name, Field_M3_name
Improved version, where the main improvement is that we show all values comma separated:
SELECT from1.keys, from1.option_name, from1.Field_M3_name,
Stuff((SELECT DISTINCT ', ' + [Option_value] FROM Value_list from2
WHERE COALESCE(from2.Option_name,'') + '|' + COALESCE(from2.Field_M3_name,'') = from1.keys FOR XML PATH(''),TYPE)
.value('text()[1]','nvarchar(max)'),1,2,N'') AS "Option values",
Stuff((SELECT DISTINCT ', ' + CAST([Sorting] AS VARCHAR) FROM Value_list from2
WHERE COALESCE(from2.Option_name,'') + '|' + COALESCE(from2.Field_M3_name,'') = from1.keys FOR XML PATH(''),TYPE)
.value('text()[1]','nvarchar(max)'),1,2,N'') AS "Sorting"
FROM ((SELECT DISTINCT COALESCE(Option_name,'') + '|' + COALESCE(Field_M3_name,'') AS keys, Option_name, Field_M3_name FROM Value_list)
-- WHERE
) from1
ORDER BY keys
Note that we have solved all possible NULL case issues that I can think of and also we fixed an error that we got for numeric values (field Sorting).

TSQL CASE WHEN THEN SYNTAX - USING REPLACE

This actually applies to a prior question, TSQL 2008 USING LTRIM(RTRIM and Still Have Spaces
I am at the point of writing a very lengthy SELECT statement using OMG PONIES statement to remove NON NULL non visible characters
(WHEN PropStreetAddr is NOT NULL THEN
(SELECT LTRIM(RTRIM((REPLACE(PropStreetAddr,
SUBSTRING(PropStreetAddr,
PATINDEX('%[^a-zA-Z0-9 '''''']%',
PropStreetAddr),
1), '') AS PropStreetAddr)
Query:
SELECT
CASE WHEN LOAN_NUMBER IS NOT NULL THEN
REPLACE( LOAN_NUMBER,SUBSTRING (LOAN_NUMBER,PATINDEX( ' %[^a-zA-Z0-9 '''''']% ' , ' ' ) as LOAN_NUMBER.
,CASE WHEN MERS_ID IS NOT NULL THEN
REPLACE( MERS_ID,SUBSTRING (MERS_ID,PATINDEX( ' %[^a-zA-Z0-9 '''''']% ' , ' ' ) as MERS_ID
...127 more lines of similar statements
As soon as I check the syntax I receive this error pointing to the first Case statement after SELECT:
Msg 156, Level 15, State 1, Line 143
Incorrect syntax near the keyword 'as'.
Could someone help me understand what I am missing?
You're missing the END from your case statements. You look like you could do with ELSEs in there as well, although these are not compulsory - if left off and nothing matches then you'll get a NULL.
CASE
WHEN something then value1
WHEN somethingelse then value2
ELSE value3
END
You are missing some right parrens.