Sql server 查找并删除重复的子字符串
我在SQLServer2008表中有一列,其中部分字符串意外重复 有没有人有一个快速简单的方法来删除尾部重复的子字符串 比如说,Sql server 查找并删除重复的子字符串,sql-server,sql-server-2008,tsql,Sql Server,Sql Server 2008,Tsql,我在SQLServer2008表中有一列,其中部分字符串意外重复 有没有人有一个快速简单的方法来删除尾部重复的子字符串 比如说, alpha\bravo\charlie\delta\charlie\delta 应该是 alpha\bravo\charlie\delta 如果您还没有数字表: SET NOCOUNT ON; DECLARE @UpperLimit INT; SET @UpperLimit = 4000; WITH n(rn) AS ( SELECT ROW_NUMBE
alpha\bravo\charlie\delta\charlie\delta
应该是
alpha\bravo\charlie\delta
如果您还没有数字表:
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]);
示例用法:
SELECT dbo.DedupeString('alpha\bravo\bravo\charlie\delta\bravo\charlie\delta');
结果:
alpha\bravo\charlie\delta
你也可以这样说:
UPDATE dbo.MessedUpTable
SET OopsColumn = dbo.DedupeString(OopsColumn);
@MikaelEriksson可能会用一种更有效的方法来使用XML消除重复项,但这是我在此之前可以提供的:-
create function RemoveDups(@S nvarchar(max)) returns nvarchar(max)
as
begin
declare @R nvarchar(max)
declare @W nvarchar(max)
set @R = ''
while len(@S) > 1
begin
-- Get the first word
set @W = left(@S, charindex('/', @S+'/')-1)
-- Add word to result if not already added
if '/'+@R not like '%/'+@W+'/%'
begin
set @R = @R + @W + '/'
end
-- Remove first word
set @S = stuff(@S, 1, charindex('/', @S+'/'), '')
end
return left(@R, len(@R)- 1)
end
应秘书长的要求。然而,我不会就什么是最快的执行提出任何要求
-- Table to replace in
declare @T table
(
ID int identity,
Value nvarchar(max)
)
-- Add some sample data
insert into @T values ('alpha/beta/alpha/gamma/delta/gamma/delta/alpha')
insert into @T values ('delta/beta/alpha/beta/alpha/gamma/delta/gamma/delta/alpha')
-- Update the column
update T
set Value = NewValue
from (
select T1.ID,
Value,
stuff((select '/' + T4.Value
from (
select T3.X.value('.', 'nvarchar(max)') as Value,
row_number() over(order by T3.X) as rn
from T2.X.nodes('/x') as T3(X)
) as T4
group by T4.Value
order by min(T4.rn)
for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '') as NewValue
from @T as T1
cross apply (select cast('<x>'+replace(T1.Value, '/', '</x><x>')+'</x>' as xml)) as T2(X)
) as T
select *
from @T
我假设您也要消除多个重复,例如source=alpha\bravo\alpha\bravo\alpha变为alpha\bravo?是否也要查找重复项,以及是整个字符串还是较大字符串中的子字符串?@TonyHopkinson:示例是整个字符串,而不是较大字符串的一部分。复制的长度会有所不同,例如ABCDBCD->ABCD.Oops。否我添加了常规行走字符串:。我将考虑一下XML的内容。我还添加了一个XML版本。要保留单词的顺序有点棘手。但是我不认为使用XML来拆分字符串比数字表更有效。我知道这是一篇比较老的帖子,但这让我很开心!
create function RemoveDups(@S nvarchar(max)) returns nvarchar(max)
as
begin
declare @R nvarchar(max)
declare @W nvarchar(max)
set @R = ''
while len(@S) > 1
begin
-- Get the first word
set @W = left(@S, charindex('/', @S+'/')-1)
-- Add word to result if not already added
if '/'+@R not like '%/'+@W+'/%'
begin
set @R = @R + @W + '/'
end
-- Remove first word
set @S = stuff(@S, 1, charindex('/', @S+'/'), '')
end
return left(@R, len(@R)- 1)
end
-- Table to replace in
declare @T table
(
ID int identity,
Value nvarchar(max)
)
-- Add some sample data
insert into @T values ('alpha/beta/alpha/gamma/delta/gamma/delta/alpha')
insert into @T values ('delta/beta/alpha/beta/alpha/gamma/delta/gamma/delta/alpha')
-- Update the column
update T
set Value = NewValue
from (
select T1.ID,
Value,
stuff((select '/' + T4.Value
from (
select T3.X.value('.', 'nvarchar(max)') as Value,
row_number() over(order by T3.X) as rn
from T2.X.nodes('/x') as T3(X)
) as T4
group by T4.Value
order by min(T4.rn)
for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '') as NewValue
from @T as T1
cross apply (select cast('<x>'+replace(T1.Value, '/', '</x><x>')+'</x>' as xml)) as T2(X)
) as T
select *
from @T