Reputation: 1559
I have a table that stores multiple values for same ID. The table looks like below:
I want to concatenate values with '&' separated.
Desired output:
My query is not producing desired output. Below is my query:
create table #temp (cid int, val1 int, val2 int, val3 int, val4 int)
insert #temp values
(1001,10,11,15,19),
(1002,15,Null,16,18),
(1003,14,18,15,NULL)
SELECT distinct t2.cid,
STUFF(( SELECT '&' + REPLACE(t1.val1,'.','') +
REPLACE(t1.val2,'.','') +
REPLACE(t1.val3,'.','') +
REPLACE(t1.val4,'.','')
FROM #temp t1
WHERE t1.cid = t2.cid
FOR XML PATH ('')
), 1, 1,'') as 'output'
FROM #temp t2
Note: I am using SQL Server 2014
Upvotes: 3
Views: 3229
Reputation: 1269443
You want concat_ws()
functionality. You can do this in SQL Server as:
select t.cid,
stuff( (coalesce('&' + t.val1, '') +
coalesce('&' + t.val2, '') +
coalesce('&' + t.val3, '') +
coalesce('&' + t.val4, '')
), 1, 1, ''
) as vals
from #temp t;
This is the most convenient equivalent to concat_ws()
that I've found in SQL Server.
If the values are integers, just cast them:
select t.cid,
stuff( (coalesce('&' + cast(t.val1 as varchar(255)), '') +
coalesce('&' + cast(t.val2 as varchar(255)), '') +
coalesce('&' + cast(t.val3 as varchar(255)), '') +
coalesce('&' + cast(t.val4 as varchar(255)), '')
), 1, 1, ''
) as vals
from #temp t;
Here is a db<>fiddle.
Upvotes: 2
Reputation: 964
For SQL Server 2017 you can use CONCAT_WS (complements to @Joakim Danielson):
SELECT cid, CONCAT_WS('&', val1, val2, val3, val4)
FROM #temp
For SQL Server 2012 you can use CONCAT:
SELECT cid, CONCAT(val1, '&', val2, '&', val3, '&', val4)
FROM #temp
For all Versions of SQL Server you can use the '+' to concatenate.
SELECT cid, val1 + '&' + val2 + '&' + val3 + '&' + val4
FROM #temp
Given that your example includes NULL and appears to be storing integers, I would recommend the following:
SELECT cid
,STUFF(COALESCE( '&' + CONVERT(VARCHAR, val1), '')
+ COALESCE( '&' + CONVERT(VARCHAR, val2), '')
+ COALESCE( '&' + CONVERT(VARCHAR, val3), '')
+ COALESCE('&' + CONVERT(VARCHAR, val4), ''), 1, 1, '')
FROM #temp
*Accepted edit to include STUFF to remove the trailing '&'
The COALESCE() will have the effect of not including NULL values in your listing, while the CONVERT to varchar will handle the Integers
Upvotes: 3
Reputation: 5940
I have a table that stores multiple values for same ID.
If CID values are not unique:
SELECT DISTINCT
t2.cid,
REPLACE(STUFF(
(
SELECT '|' + CAST(val AS VARCHAR(50))
FROM
(
SELECT cid, val1 AS val FROM #temp
UNION ALL
SELECT cid, val2 AS val FROM #temp
UNION ALL
SELECT cid, val3 AS val FROM #temp
UNION ALL
SELECT cid, val4 AS val FROM #temp
) t1
WHERE t1.cid = t2.cid
AND t1.val IS NOT NULL
FOR XML PATH('')
), 1, 1, ''), '|', '&') AS 'output'
FROM #temp t2;
Results to:
cid output
1001 10&11&15&19
1002 15&16&18
1003 14&18&15
Otherwise, CONCAT
or CONCAT_WS
as other members correctly suggested is more elegant solution
Upvotes: 1
Reputation: 51851
Use CONCAT_WS for this
SELECT cid, CONCAT_WS('&', val1, val2, val3, val4)
FROM #temp
Upvotes: 2