Получить отличительные символы из заданной строки на сервере SQL - PullRequest
2 голосов
/ 14 марта 2019

Мне нужна функция T-SQL, которая удаляет дубликаты символов в заданной строке:

для примера Fn_Remove ('AVGHAHA'), она возвращает AVGH

Ответы [ 4 ]

2 голосов
/ 14 марта 2019

Используя NGrams8K, вы можете разбить строку на отдельные "токены" символов, применить число к этому набору символов, а затем перестроить, используя только первый из каждого символа:

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);
1 голос
/ 14 марта 2019

Другим подходом может быть использование рекурсивного CTE, которое я узнал вчера из одного из ответов @Gordon Linoff.

;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);

Онлайн-демонстрация

Редактировать :

Как пользовательская функция.

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; 
1 голос
/ 14 марта 2019

Сначала создайте таблицу чисел с возрастающими целыми числами от 1 и выше.

Тогда вы можете использовать

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

Используется семантика сопоставления по умолчанию для равенства. Используйте явное предложение COLLATE, если хотите что-то другое.

Если у вас версия, которая не поддерживает STRING_AGG, вы можете использовать XML PATH для конкатенации строк.

0 голосов
/ 14 марта 2019

спасибо вам ребята за вашу помощь но мне нужна была функция и я нашел решение

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...