Nếu bạn chưa có bảng số:
SET NOCOUNT ON;
DECLARE @UpperLimit INT;
SET @UpperLimit = 4000;
WITH n(rn) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_columns
)
SELECT [Number] = rn - 1
INTO dbo.Numbers FROM n
WHERE rn <= @UpperLimit + 1;
CREATE UNIQUE CLUSTERED INDEX n ON dbo.Numbers([Number]);
Bây giờ là một hàm chia chung, sẽ biến chuỗi được phân tách của bạn thành một tập hợp:
CREATE FUNCTION dbo.SplitString
(
@List NVARCHAR(MAX),
@Delim CHAR(1)
)
RETURNS TABLE
AS
RETURN ( SELECT
rn,
vn = ROW_NUMBER() OVER (PARTITION BY [Value] ORDER BY rn),
[Value]
FROM
(
SELECT
rn = ROW_NUMBER() OVER (ORDER BY CHARINDEX(@Delim, @List + @Delim)),
[Value] = LTRIM(RTRIM(SUBSTRING(@List, [Number],
CHARINDEX(@Delim, @List + @Delim, [Number]) - [Number])))
FROM dbo.Numbers
WHERE Number <= LEN(@List)
AND SUBSTRING(@Delim + @List, [Number], 1) = @Delim
) AS x
);
GO
Và sau đó là một chức năng đặt chúng lại với nhau:
CREATE FUNCTION dbo.DedupeString
(
@List NVARCHAR(MAX)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
RETURN ( SELECT newval = STUFF((
SELECT '\' + x.[Value] FROM dbo.SplitString(@List, '\') AS x
WHERE (x.vn = 1)
ORDER BY x.rn
FOR XML PATH, TYPE).value('.', 'nvarchar(max)'), 1, 1, '')
);
END
GO
Cách sử dụng mẫu:
SELECT dbo.DedupeString('alpha\bravo\bravo\charlie\delta\bravo\charlie\delta');
Kết quả:
alpha\bravo\charlie\delta
Bạn cũng có thể nói điều gì đó như:
UPDATE dbo.MessedUpTable
SET OopsColumn = dbo.DedupeString(OopsColumn);
@MikaelEriksson có thể sẽ áp dụng một cách hiệu quả hơn để sử dụng XML để loại bỏ các bản sao, nhưng đó là những gì tôi có thể cung cấp cho đến lúc đó. :-)