【问题标题】:Get Distinct characters from a given string in sql server从sql server中的给定字符串中获取不同的字符
【发布时间】:2019-03-14 20:53:45
【问题描述】:

我需要一个 T-SQL 函数来删除给定字符串中的重复字符

例如 Fn_Remove('AVGHAHA') 它将返回 AVGH

【问题讨论】:

  • 您可能必须编写一个 UDF 来处理这个问题。我不确定 SQL Server 中开箱即用的任何东西都会有所帮助。
  • 到目前为止你尝试过什么?堆栈溢出不是一个用于说明您“需要”什么的网站,而是用于询问编码问题的网站。是否要分别处理大写和小写字符?
  • A 也是重复字符,为什么没有从您的示例中删除?
  • 我相信“重复”是指“角色的第二次或更多次出现”@GuidoG。请注意,第一个 A 存在(在字符串的开头),第一个 H 也存在(在位置 4),后面出现的任何字符都不存在。

标签: sql-server string function tsql


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    首先创建一个 Numbers 表,其中的整数从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 进行字符串连接。

    【讨论】:

      【解决方案3】:

      另一种方法可以使用递归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);
      

      Online Demo

      编辑

      作为用户定义的函数。

      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; 
      

      【讨论】:

      • 它工作得很好,现在我正在努力将它添加到一个函数中
      • 正如我所说的我是新手
      • @yassinemhadhbi,我已将其创建为函数,您可以查看答案。
      【解决方案4】:

      谢谢你们的帮助 但我需要一个功能 我找到了解决方案

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-08-22
        • 2020-09-29
        • 2020-07-25
        • 2012-02-10
        • 2023-01-26
        • 1970-01-01
        • 2021-12-08
        相关资源
        最近更新 更多