Reputation: 141
My table is as below
ID | Name | City
------ | ------ | ------
1 | ABC | London, Paris
1 | ABC | Paris
1 | ABC | Japan
2 | XYZ | Delhi
2 | XYZ | Delhi, New York
My output needs to be like this:
ID | Name | City
------ | ------ | ------
1 | ABC | London, Paris, Japan
2 | XYZ | Delhi, New York
I see it as a 2 step process:
Concatenate all the unique cities for each ID and Name. Example: For ID 1 and Name ABC Cities would be London, Paris, Japan
Update the concatenated string by grouping the ID and Name.
I am able to do this for just one group, but how do I do this for all the different groups in the table?
Also, would cursors come into picture here when I want to update the string to all the rows matching the ID and Name.
Any help or idea on this would be appreciated.
Upvotes: 0
Views: 2688
Reputation: 39457
You should consider normalizing your table first.
Here, you first want to convert all the comma separated values into separate rows and then, group them together using STUFF and FOR XML PATH.
with your_table (ID, name, City)
as (
select 1, 'ABC', 'London, Paris'
union all
select 1, 'ABC', 'Paris'
union all
select 1, 'ABC', 'Japan'
union all
select 2, 'XYZ', 'Delhi'
union all
select 2, 'XYZ', 'Delhi, New York'
), your_table_modified
as (
select distinct id, name, Split.a.value('.', 'varchar(100)') City
from (
select id, name, cast('<x>' + replace(City, ', ', '</x><x>') + '</x>' as xml) as x
from your_table
) t
cross apply x.nodes('/x') as Split(a)
)
select id, name, stuff((
select ', ' + city
from your_table_modified t2
where t.id = t2.id
for xml path(''), type
).value('(./text())[1]', 'varchar(max)')
, 1, 2, '')
from your_table_modified t
group by id, name;
Produces:
Upvotes: 7
Reputation: 317
Try this:
select y.id,y.name,y.city from (
select id,name, case when Id=1 and name='ABC' then 'London,Paris,Japan'
when Id=2 and name='XYZ' then 'Delhi,Newyork'
end as CIty
,row_number () over (partition by id order by name asc) as rnk
from Yourtable
)y
where y.rnk=1
Upvotes: -1