select
e.*,
x.[expected_result]
from
employee e
cross apply
(select
stuff((
select
distinct
','+ltrim(rtrim(value))
from
string_split(e.details, ',')
for xml path(''))
,1 ,1 ,'') as [expected_result]) as x
Create FUNCTION fn_RemoveDuplicate
(
@inputstring varchar(max)
)
RETURNS varchar(max)
AS
BEGIN
declare @test2 varchar(max)
declare @test1 xml =cast(@inputstring as xml)
SET @test2 ='<Details>'+ cast(('<detail><value1>'+replace(@inputstring,',' ,'</value1></detail><detail><value1>')+'</value1></detail>') as varchar(max))+'</Details>'
set @test1=cast(@test2 as xml)
DECLARE @Details varchar(max)
SET @Details = NULL
SELECT @Details = COALESCE(@Details + ',','') + [value1]
FROM (select distinct
t.x.value('value1[1]','Varchar(50)') as value1
from @test1.nodes('/Details/detail') t(x)) as p
return @Details
END
1
解决方案的想法是使用表值函数(fn_SplitString),并根据不同的值组合结果表 .
以下查询应该执行您想要的操作:
SELECT
[ID],[Details],
[cleansedDetails] = (SELECT
STUFF((
SELECT
DISTINCT ','+LTRIM(RTRIM(ISNULL(ncValue,cvalue)))
FROM
fn_SplitString([Details], ',')
FOR XML PATH(''))
,1 ,1 ,''))
FROM [dbo].[tb_Employee]
3 回答
如果您使用 SQL Server 2016 or later ,以下答案可以解决您的问题:
我通过使用
string_split()
和stuff()
函数来解决它 . 以下链接可帮助您了解它们的工作原理:STRING_SPLIT (Transact-SQL)
STUFF (Transact-SQL)
SQL Server CROSS APPLY and OUTER APPLY
使用逗号分隔值存储数据不是一个好习惯 . 如果有可能,我强烈建议您更改模型 .
我创建了一个标量值函数 fn_RemoveDuplicate ,它将varchar作为输入并返回一个varchar(没有重复项) .
然后你可以用它作为
解决方案的想法是使用表值函数(fn_SplitString),并根据不同的值组合结果表 .
以下查询应该执行您想要的操作:
在这个db<>fiddle中,您可以找到我的示例数据的DDL和DML以及表值函数fn_SplitString的定义 . 您可以检查代码在不同方案中的工作方式 .