问题
i need a T-SQL function that remove duplicate charcters in a give String
for exemple Fn_Remove('AVGHAHA') it will returns AVGH
回答1:
Using NGrams8K, you can split the string into individual character "tokens", apply a number to that character set, and then rebuild with only the first of each character:
WITH CTE AS(
SELECT V.S,
N.position,
N.token,
ROW_NUMBER() OVER (PARTITION BY N.token ORDER BY N.position) AS RN
FROM (VALUES('AVGHAHA'))V(S)
CROSS APPLY dbo.NGrams8k(V.S,1) N)
SELECT V.S,
(SELECT '' + C.token
FROM CTE C
WHERE C.S = V.S
AND C.RN = 1
ORDER BY C.position
FOR XML PATH('')) AS Replaced
FROM (VALUES('AVGHAHA'))V(S);
回答2:
First create a Numbers table with ascending integers from 1
upwards.
Then you can use
SELECT STRING_AGG (Char, '') WITHIN GROUP (ORDER BY Pos ASC) AS csv
FROM
(
SELECT SUBSTRING(@String, number, 1) AS Char, MIN(number) AS Pos
FROM Nums
WHERE number <= LEN(@String)
GROUP BY SUBSTRING(@String, number, 1)
) T
This uses the semantics of your default collation for equality. Use an explicit COLLATE
clause if you want something different.
If you are on a version that does not support STRING_AGG
you can use XML PATH
for string concatenation.
回答3:
Another approach can be using recursive CTE
, which I learned yesterday from one of @Gordon Linoff's answer.
;with cte as (
select v.input, convert(varchar(max), '') as updated, 1 as lev
from (values ('AVGHAHA')) v(input)
union all
select stuff(input, 1, 1, ''),
(case when charindex(left(input, 1),updated) > 0 then updated else concat(updated , left(input, 1)) end),
lev + 1
from cte
where input > ''
)
select top (1) with ties updated
from cte
order by row_number() over (order by lev desc);
Online Demo
Edit:
As a user defined function.
CREATE FUNCTION dbo.Fn_Remove(@Input varchar(100))
RETURNS varchar(100)
AS
-- Returns the stock level for the product.
BEGIN
DECLARE @ret varchar(100)
;with cte as (
select v.input, convert(varchar(max), '') as updated, 1 as lev
from (values (@Input)) v(input)
union all
select stuff(input, 1, 1, ''),
(case when charindex(left(input, 1),updated) > 0 then updated else concat(updated , left(input, 1)) end),
lev + 1
from cte
where input > ''
)
select top (1) @ret=updated
from cte
order by lev desc
RETURN @ret;
END;
回答4:
thank you guys for your help but i needed a function and i found a solution
USE [DATAWARHOUSE]
GO
/****** Object: UserDefinedFunction [dbo].[EliminateRedoblons] Script Date: 3/14/2019 1:52:02 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[EliminateRedoblons](@str VARCHAR(500))
RETURNS varchar(500)
begin
DECLARE
@resultat VARCHAR(500)='',
@i INT=0,
@is INT,
@c NVARCHAR(1)
while @i<=LEN(@str)
BEGIN
SET @i=@i+1
SET @c=substring(@str,@i,1)
SET @is =CHARINDEX(@c,@resultat)
IF @IS=0
BEGIN
SET @resultat=@resultat+@c
END
END
return @resultat
END
GO
来源:https://stackoverflow.com/questions/55160719/get-distinct-characters-from-a-given-string-in-sql-server