Multiple column values into a single column as comma separated value - sql

I have a table CommentsTable with columns like, CommentA, CommentB, CommentC, CommentD, CommentE.
All comments columns are VARCHAR (200), by default all columns are NULL also.
The data looks like:
CommentId CommentA CommentB CommentC CommentD CommentE
---------------------------------------------------------------------
12345 NULL C 001 C 002 NULL C 003
45678 C 005 NULL NULL C 007 NULL
67890 C 010 NULL C 011 C 012 NULL
36912 C 021 C 023 C 024 C 025 C 026
I need to avoid the null values and the remaining values are concatenate with comma.
So, the expected output like:
CommentId CommetDetails
-------------------------------
12345 C 001, C 002, C 003
45678 C 005, C 007
67890 C 010, C 011, C 012
36912 C 021, C 023, C 024, C 025, C 026
I tried with simple query:
SELECT CommentId, ISNULL(CommentA, '') + ', ' + ISNULL(CommentB, '') + ', ' +
ISNULL(CommentC, '') + ', ' + ISNULL(CommentD, '') + ', ' +
ISNULL(CommentE, '') [CommentDetails]
FROM CommentsTable
WHERE ...... --Some conditions
But the unwanted comma are occurred, So added IIF
SELECT CommentId,
IIF(ISNULL(CommentA, '') <> '', (CommentA + ', '), '') +
IIF(ISNULL(CommentB, '') <> '', (CommentB + ', '), '') +
IIF(ISNULL(CommentC, '') <> '', (CommentC + ', '), '') +
IIF(ISNULL(CommentD, '') <> '', (CommentD + ', '), '') +
ISNULL(CommentE, '') [CommentDetails]
FROM CommentsTable
WHERE ...... --Some conditions
But here also, the comma occurred in the last position for some cases (If CommentD, CommetE are NULL.
Is there any way to achieve to solve for all the cases.
Sample SQL Fiddle

You can use ISNULL like this ISNULL(',' + CommentA, '') and write your query like this.
SELECT CommentId,
STUFF(
ISNULL(',' + CommentA, '') +
ISNULL(',' + CommentB, '') +
ISNULL(',' + CommentC, '') +
ISNULL(',' + CommentD, '') +
ISNULL(',' + CommentE, ''),1,1,'') as [CommentDetails]
FROM CommentsTable
WHERE ...... //Some conditions
See result in SQL Fiddle.

The above answers are correct and no challenge to the accepted answer but in case some columns have empty string instead of null then below might help. Please don't hesitate for a better approach and correct me if it's wrong.
SELECT CommentId,
STUFF(
ISNULL(',' + CASE WHEN CommentA= '' THEN NULL ELSE CommentA END, '') +
ISNULL(',' + CASE WHEN CommentB= '' THEN NULL ELSE CommentB END, '') +
ISNULL(',' + CASE WHEN CommentC= '' THEN NULL ELSE CommentC END, '') +
ISNULL(',' + CASE WHEN CommentD= '' THEN NULL ELSE CommentD END, '') +
ISNULL(',' + CASE WHEN CommentE= '' THEN NULL ELSE CommentE END, ''),1,1,'') as [CommentDetails]
FROM CommentsTable

create table #test
(
CommentId int,
CommentA nvarchar(200),
CommentB nvarchar(200),
CommentC nvarchar(200),
CommentD nvarchar(200),
CommentE nvarchar(200)
)
insert into #test values(12345,NULL,'C 001','C 002',NULL,'C 003')
insert into #test values(45678,'C 005',NULL,NULL,'C 007',NULL)
insert into #test values(67890,'C 010',NULL,'C 011','C 012',NULL)
insert into #test values(36912,'C 021','C 023','C 024','C 025','C 026')
Use This Code:
select CommentId,STUFF(ISNULL(','+CommentA,'')+
ISNULL(','+CommentB,'')+
ISNULL(','+CommentC,'')+
ISNULL(','+CommentD,'')+
ISNULL(','+CommentE,''),1,1,'') As Comment
from #test
order by CommentId

Related

Extract forename if the character is more then 2 letter

I have to get the forename from the c.forename if c.known_as column is null or blank.
This i achieved with case when statement using
CASE
WHEN IND.KNOWN_AS IS NULL OR ind.KNOWN_AS=''
THEN ind.FORENAMES
ELSE ind.KNOWN_AS
END AS 'Known As'
My issue is in the forename column i have name like Jhon Smith where i would like to extract only John, below is an example what i want to achieve
Desire output c.forename
John Mr John
Jhon Jhon Smith
blank Jo
blank J
So , basically it will only take forname skipping 'Mr', 2nd it should take only forename which has more than 2 character.
My current query is:
Select ind.FORENAMES,
ind.KNOWN_AS,
case when (known_as is null or known_as = '' ) and charindex(' ', forenames) > 2
then substring(forenames, 1, charindex(' ', forenames) - 1) end as FORENAMES2,
output
from individual ind
join member m on m.individual_ref=ind.individual_ref
and m.MEMBERSHIP_NO in ('001','002','003','004','005','006','007')
where m.member_status=33
You could use following case when statement to verify your conditions:
For SQL Server:
case when (c.known_as is null or c.known_as = '' )
and charindex(' ', c.forename) > 3 then substring(c.forename, 1, charindex(' ', c.forename) - 1) end
For MySQL:
case when (c.known_as is null or c.known_as = '' )
and locate(' ', c.forename) > 3 then substring(c.forename, 1, locate(' ', c.forename) - 1) end
Little explanation: if the first name must be longer than 2 characters, that means that first space must occur at least at index 4. And that what the condition is about: locate(' ', c.forename) > 3 or substring(' ', c.forename) > 3
NOTE
You have to first strip down all occurences of Mr, Mrs, Ms in c.forename column, like this (syntax for MySQL and SQL Server):
replace(replace(replace(c.forename, 'Mrs ', ''), 'Mr ', ''), 'Ms ', '')
You have to include it in your query lke this:
Select FORENAMES,
KNOWN_AS,
case when (known_as is null or known_as = '' ) and charindex(' ', FORENAMES2) > 2
then substring(FORENAMES2, 1, charindex(' ', FORENAMES2) - 1) end as FORENAMES2,
output
from (
Select ind.FORENAMES,
ind.KNOWN_AS,
replace(replace(replace(ind.FORENAMES, 'Mrs ', ''), 'Mr ', ''), 'Ms ', '') FORENAMES2,
output
from individual ind
join member m on m.individual_ref = ind.individual_ref
where m.member_status=33
and m.MEMBERSHIP_NO in ('001','002','003','004','005','006','007')
)
Try this:
DECLARE #DataSource TABLE
(
[name] VARCHAR(32)
);
INSERT INTO #DataSource ([name])
VALUES (' Mr John ')
,('Jhon Smith')
,(' Jo ')
,(' J ');
WITH SanitizeDataSoruce ([name], [name_reversed]) AS
(
SELECT LTRIM(RTRIM([name]))
,REVERSE(LTRIM(RTRIM([name])))
FROM #DataSource
)
SELECT [name]
,CASE
WHEN CHARINDEX(' ', [name]) > 1 THEN REVERSE(SUBSTRING([name_reversed], 0, CHARINDEX(' ', [name_reversed])))
ELSE ''
END
FROM SanitizeDataSoruce;

sql concatenate columns if one or more columns is not null

I have a table that looks something like this:
BuildingID | RouterType | RouterPort | RouterInstaller | Notes
-----------+------------+------------+-----------------+-------
282 | Linksys | 1990 | Super | NULL
307 | Sonic Wall | NULL | Greg | NULL
311 | NULL | NULL | NULL | NULL
I would like the Notes column to be the concatenation of the 2nd 3rd and 4th columns only if the column is not null.
line 1: Router Type: Linksys Router Port: 1990 Router Installer: Super
line 2: Router Type: Sonic Wall Router Installer: Greg
line 3: NULL
Also the word 'Router Type:' should only come in if the value of Router type is not null etc.
I am pretty new to SQL - any help would be greatly appreciated.
Try this:
select case when [Note] = '' then null else Note from (
select BulidingId,
case when RouterType is null then '' else 'Router Type: ' + RouterType + '; '+
case when RouterPort is null then '' else 'Router Port: ' + RouterPort + '; '+
case when RouterInstaller is null then '' else 'Router Port: ' + RouterInstaller + '; '+
case when Notes is null then '' else 'Notes: ' + Notes + '; ' [Note]
from MY_TABLE
) a
This will do it by combining Coalesce and Concat. The column names are added as labels to the column values.
select COALESCE(Notes, COALESCE(CONCAT(COALESCE(CONCAT('RouterType: ',RouterType),''),
COALESCE(CONCAT(' RouterPort: ',RouterPort ),''),
COALESCE(CONCAT(' RouterInstaller: ',RouterInstaller),'')), NULL)) as Notes
from yourTable;
Try this select query, i think it will help you:
SELECT CASE WHEN (
COL2 IS NOT NULL
AND COL3 IS NOT NULL
AND COL4 IS NOT NULL )
THEN
CONCAT(COL2,' ', COL3,' ', COL4) END as ConcatedData,
* from YOUR_TABLE;
To get the spacing correct, I recommend:
select stuff(coalesce(' RouterType: ' + RouterType), '') +
coalesce(' RouterPort: ' + RouterPort ), '') +
coalesce(' RouterInstaller: ', RouterInstaller), ''),
1, 1, ''
) as Notes
from t;
In an update:
update t
set notes = stuff(coalesce(' RouterType: ' + RouterType), '') +
coalesce(' RouterPort: ' + RouterPort ), '') +
coalesce(' RouterInstaller: ', RouterInstaller), ''),
1, 1, ''
);
Note: This will not put in a NULL value, instead using an empty string. That is easily fixed -- if it is a problem:
update t
set notes = nullif(stuff(coalesce(' RouterType: ' + RouterType), '') +
coalesce(' RouterPort: ' + RouterPort ), '') +
coalesce(' RouterInstaller: ', RouterInstaller), ''),
1, 1, ''
), ''
)
Try this update statement:
DECLARE #TEMP_TABLE TABLE (
BUILDING_ID INT,
ROUTER_TYPE VARCHAR(20) NULL,
PORT INT NULL,
ROUTER_INSTALLER VARCHAR(20) NULL,
NOTES VARCHAR(1000) NULL
)
INSERT INTO #TEMP_TABLE VALUES(1,'Linksys Router', 1990, 'Super', NULL)
INSERT INTO #TEMP_TABLE VALUES(2,NULL, NULL, NULL, NULL)
UPDATE #TEMP_TABLE
SET NOTES = COALESCE(' Router type: ' + ROUTER_TYPE,'') + COALESCE(' Port: ' + CAST(PORT AS VARCHAR),'') + COALESCE(' Router installer: ' + ROUTER_INSTALLER,'')
WHERE ROUTER_TYPE IS NOT NULL OR PORT IS NOT NULL OR ROUTER_INSTALLER IS NOT NULL
SELECT * FROM #TEMP_TABLE

Concatenate first name, last name and middle name with comma

I want to concatenate 3 columns in SQL server as below:
MAX(LTRIM(RTRIM((ISNULL(LastName,'') +
', ' +
ISNULL(FirstName,'') +
', ' +
ISNULL(MiddleName,''))))) AS FullName
I have used value of this column in SELECT clause as:
MAX(FullName) AS FullName,
I would like to handle NULL values, in case all 3 last name, middle name and first name are BLANK or NULL. The query used above will show " , , " in case all 3 columns are NULL or BLANK. But I want to show "N/A" in such case.
Thanks in advance.
You could use a CASE expression:
SELECT MAX(CASE WHEN ISNULL(FirstName, '') = '' AND
ISNULL(MiddleName, '') = '' AND
ISNULL(LastName, '') = ''
THEN 'N/A'
ELSE LTRIM(RTRIM((ISNULL(LastName,'') + ', ' +
ISNULL(FirstName,'') + ', ' +
ISNULL(MiddleName,''))))
END) AS FullName
FROM yourTable
...
Check with COALESCE and then CASE Statement:
Declare #FirstName VARCHAR(50)='',#MiddleName VARCHAR(50),#LastName VARCHAR(50)
SELECT
CASE WHEN ISNULL(COALESCE(#FirstName,#MiddleName,#LastName),'')<>''
THEN ISNULL(#FirstName,'')+',' +ISNULL(#MiddleName,'')+','+ISNULL(#LastName,'')
ELSE 'N/A' END AS FullName
Use Concat like below this will do implicit conversion. So no need to use ISNULL.
select isnull(MAX(LTRIM(RTRIM((concat(LastName,
', ' ,
FirstName,
', ' ,
MiddleName,''))))) ,'n/a')AS FullName from table
The below method may seem quite complicated, but it does make adding or removing columns much simpler, and for all its perceived complexity it isn't actually doing that much under the hood, so doesn't add much overhead.
The first step is to unpivot each of your columns to rows with a common column name, so you would turn
FirstName MiddleName LastName
------------------------------------
A NULL C
Into
Name
------
A
NULL
C
Using CROSS APPLY along with the table value constructor VALUES
SELECT x.Name
FROM (VALUES ('A', NULL,'C')) AS t (FirstName, MiddleName, LastName)
CROSS APPLY (VALUES (1, t.FirstName), (2, t.MiddleName), (3, t.LastName)) x (SortOrder, Name)
ORDER BY x.SortOrder
Then you can remove NULLs and blanks with WHERE ISNULL(Name, '') <> '', then you only have valid data to concatenate together which you can do using SQL Server's XML Extensions. So you end up with a full query like:
WITH TestData AS
( SELECT *
FROM (VALUES ('A'), (NULL)) AS f (FirstName)
CROSS JOIN (VALUES ('B'), (NULL)) AS m (MiddleName)
CROSS JOIN (VALUES ('C'), (NULL)) AS l (LastName)
)
SELECT t.*,
NamesConcat = ISNULL(STUFF(NamesConcat.value('.', 'NVARCHAR(MAX)'), 1, 2, ''), 'N/A')
FROM TestData AS t
CROSS APPLY
( SELECT ', ' + x.Name
FROM (VALUES
(1, t.FirstName),
(2, t.MiddleName),
(3, t.LastName)
) x (SortOrder, Name)
WHERE ISNULL(x.Name, '') <> '' -- NOT BLANK OR NULL
ORDER BY x.SortOrder
FOR XML PATH(''), TYPE
) x (NamesConcat);
Result
FirstName MiddleName LastName NamesConcat
-------------------------------------------------
A B C A, B, C
A NULL C A, C
A B NULL A, B
A NULL NULL A
NULL B C B, C
NULL NULL C C
NULL B NULL B
NULL NULL NULL N/A
select Isnull(FirstName,' ') +' '+ ','+ Isnull(MiddleName,' ')+' '+ ' ,'+ Isnull(Lastname,' ') as Name from personaldata
select FirstName +' '+','+ MiddleName +' '+',' + Lastname as Name from personaldata
Note: The Second query will work fine if all value present and if anyone is null then it will return null for Name, to avoid such kind of concern please use the first query.

SQL combine columns strings

I have an sql table that looks like the following
p1 c1 c2 c3 c4 c5 c6 c7
A B C D E F NULL NULL
A B C NULL NULL NULL NULL NULL
A B NULL NULL NULL NULL NULL NULL
A NULL NULL NULL NULL NULL NULL NULL
i need a select sql query with 1 column and the output to look like
Result
A > B > C > D > E > F
A > B > C
A
i tried nested select case however i am getting only nulls
select
case when x.p1 IS not NULL then(
x.p1 + case when x.c1 IS not NULL then(
' > '+ x.c1 + case when x.c2 IS not NULL then(
' > '+ x.c2 + case when x.c3 IS not NULL then(
' > '+ x.c3 + case when x.c4 IS not NULL then(
' > '+ x.c4 + case when x.c5 IS not NULL then(
' > '+ x.c5 + case when x.c6 IS not NULL then(
' > '+ x.c6 + case when x.c7 IS not NULL then(
' > '+ x.c7 )end )end )end )end )end )end )end) end as tree
from mytable
is there a better way to get the result i want?
what is wrong with my select case?
Based on the fact that in TSQL 'a string' + null equals null, you can simplify the query to this:
select
p1
+ isnull(('>' + c1), '')
+ isnull(('>' + c2), '')
+ isnull(('>' + c3), '')
+ isnull(('>' + c4), '')
+ isnull(('>' + c5), '')
+ isnull(('>' + c6), '')
+ isnull(('>' + c7), '')
from mytable
SQLFiddle link: http://www.sqlfiddle.com/#!3/02b05/8
what is wrong with my select case?
You are using the table alias x which appears to not be defined anywhere.
I made your query work in two steps:
define the x table alias. For that, simply write mytable x at the end instead of just mytable
after the above fix, it'll still return null, because the case statements only have one branch and when the condition is not met they still return null. To fix that, replace every end with else '' end (to return an empty string rather than a null)
Here's your version working: http://www.sqlfiddle.com/#!3/02b05/11

How To Use COALESCE() to Add Additional Characters

I have the following syntax on my SELECT Statement:
CONCAT(first_name, " ", COALESCE(middle_initial), " ", last_name) AS full_name
Obviously, what I get is the following:
For first_name='John' and middle_initial='A.' and last_name='Smith'
I get 'John A. Smith'
That is fine and is the desired result.
But I get an extra space for the following data (which I clearly understand why):
For first_name='John' and middle_initial='' and last_name='Smith'
I get 'John Smith'
Is there a way with COALESCE() to append " " if the condition returns a non-null value?
Thank you.
When middle_initial has '', you would want to:
SELECT CONCAT(first_name, ' ',
CASE
WHEN middle_initial is null OR middle_initial = '' then ''
ELSE CONCAT(middle_initial, ' ')
END
, last_name) AS full_name
SQLFiddle Example
COALESCE is used for checking NULL values, not handling empty strings, ''
select concat(first_name , ' ' ,
case when middle_initial is null then ''
when middle_initial = '' then ''
else concat(middle_initial, ' ') end ,
last_name)
this query asumes that first_name and last_name are not null nor empty string, in that case you can apply same logic to that fields
Try this
SELECT rtrim(Coalesce(first_name + ' ','')
+ Coalesce(nullif(middle_name,'') + ' ', '')
+ Coalesce(nullif(last_name,'') + ' ', ''))
FROM #table
SELECT rtrim(Coalesce('John' + ' ','')
+ Coalesce(nullif('A.','') + ' ', '')
+ Coalesce(nullif('Smith','') + ' ', ''))
SELECT rtrim(Coalesce('John' + ' ','')
+ Coalesce(nullif('','') + ' ', '')
+ Coalesce(nullif('Smith','') + ' ', ''))
I think best way is to do it like this. You can use such a constraction for any number of fields, variables and so on. Also it will correctly show you John or John A.
declare #Temp_Table table (first_name nvarchar(128), middle_initial nvarchar(128), last_name nvarchar(128))
insert into #Temp_Table
select 'John', null, 'Smith' union all
select 'John', 'A.', 'Smith' union all
select 'John', 'A.', null union all
select 'John', null, null
select
*,
stuff
(
isnull(' ' + nullif(first_name, ''), '') +
isnull(' ' + nullif(middle_initial, ''), '') +
isnull(' ' + nullif(last_name, ''), ''),
1, 1, ''
)
from #Temp_Table