我有一个选择查询说
select details,* from employee
details
列值可以为“非常好,非常好,不好” 。它可以具有任意数量的逗号分隔值。
我想比较每个逗号之间的文本,并删除重复项。
结果必须像“非常好,不好”
我如何实现它。请帮忙。
谢谢。
答案 0 :(得分:1)
如果您使用 SQL Server 2016或更高版本,则以下答案可以解决您的问题:
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
我通过使用string_split()
和stuff()
函数来解决这个问题。以下链接可帮助您了解它们的工作原理:
SQL Server CROSS APPLY and OUTER APPLY
以逗号分隔值存储数据不是一个好习惯。我还强烈建议您尽可能更改模型。
答案 1 :(得分:1)
我已经创建了一个标量值函数 fn_RemoveDuplicate ,该函数将varchar作为输入并返回一个varchar(没有重复项)。
然后可以将其用作
从员工中选择dbo.fn_RemoveDuplicate(details,*)
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
答案 2 :(得分: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]
在此db<>fiddle中,您可以找到示例数据的DDL和DML以及表值函数fn_SplitString的定义。您可以检查代码在不同情况下的工作方式。