The real solution:
Fix your design.
The real question here is why are you storing delimited data in your database in the first place? That is your real problem, and so the real solution is to fix your design. Normalise your data, don't store delimited data. It breaks multiple basic rules in for (relational) data. Move to multiple tables with many to one/many relationships.
Saying that, however, you can do this with STRING_SPLIT
and STRING_AGG
. Note that as STRING_SPLIT
doesn't return an ordinal value, the order the values are added back to the string are unlikely to follow the original ordinal positions.
I also assume you're using a fully supported version of SQL Server, without evidence to the contrary. If not, you'll need to use a user defined splitter function and the FOR XML PATH
methods for the 2 functions respectively.
WITH DistinctValues AS(
SELECT DISTINCT
V.DenormalisedData,
SS.[Value]
FROM (VALUES('dog,cat,dog,dog'),
('dog,dog,bird,cat'),
('panda,bird,cat'))V(DenormalisedData)
CROSS APPLY STRING_SPLIT(V.DenormalisedData,',') SS)
SELECT STRING_AGG(DV.[Value],',') AS RedenormalisedData
FROM DistinctValues DV
GROUP BY DenormalisedData;