Martin's answer is perfect if you don't need an explicit guarantee that the string will get reassembled in the same order as it arrived (while you should generally observe that to be the case, that's no guarantee). If you do need that guarantee, then on SQL Server 2022+ (or Azure SQL Database/MI), you can use the new enable_ordinal
argument of STRING_SPLIT
:
SELECT @BaseStringValues = STRING_AGG(value, ',')
WITHIN GROUP (ORDER BY ordinal)
FROM
(
SELECT value, ordinal
FROM STRING_SPLIT(@BaseStringValues, ',', 1) -- order matters
) AS x
WHERE NOT EXISTS
(
SELECT 1
FROM STRING_SPLIT(@ParamValues, ',', 0) -- order doesn't matter
WHERE value = x.value
);
If you are on SQL Server 2017 or better, you can use OPENJSON
:
SET @BaseStringValues = '["' + REPLACE(
STRING_ESCAPE(@BaseStringValues, 'json'), ',','","') + '"]';
SELECT @BaseStringValues = STRING_AGG(value, ',')
WITHIN GROUP (ORDER BY [key])
FROM OPENJSON(@BaseStringValues) AS x
WHERE NOT EXISTS
(
SELECT 1 FROM STRING_SPLIT(@ParamValues, ',')
WHERE value = x.value
);
If you are on SQL Server 2016 or lower, you are running an unsupported version and will have to resort to really ugly FOR XML PATH
aggregation, which I talked about here, and an order-observing table-valued function to perform the split, which I talked about here.
- db<>fiddle - now with an older-than-2017 version too.