【问题标题】:sql to pick apart a string of a persons name and output the initialssql 挑选出一串人名并输出姓名首字母
【发布时间】:2011-02-01 16:45:05
【问题描述】:

我怎样才能让 SQL 进行刺痛并返回传递给它的每个单词的第一个字母。

我想使用这个 UDF 为我在数据库中的人名生成首字母。

名称可以是 2 (fname, lname) 或 3(...mname) 字

我正在使用 sql2005

【问题讨论】:

    标签: sql-server-2005 user-defined-functions


    【解决方案1】:

    这应该适用于“Firstname Lastname”和“Firstname Middlename Lastname”组合。

    DECLARE @name AS NVARCHAR(50) 
    SET @name = 'Firstname Middle Lastname' 
    
    
    SELECT SUBSTRING(@name, 1, 1) +     --First initial
        SUBSTRING(@name, CHARINDEX(' ', @name) + 1, 1) +    --Middle/Last initial
        CASE WHEN 0 <>  CHARINDEX(' ', @name, CHARINDEX(' ', @name) + 1) -- More than two words 
            THEN SUBSTRING(@name, CHARINDEX(' ', @name, CHARINDEX(' ', @name) + 1) + 1, 1)  --Last initial
        ELSE '' --Have to add empty string to avoid NULLing entire result
        END
    

    当然,如果用户出于某种原因在他们的姓名之一中 有一个空格,则解析它时会遇到问题,但我怀疑在不将您的姓名存储在单独的字段。

    【讨论】:

      【解决方案2】:
      CREATE FUNCTION dbo.GetFirstLetter ( @Array VARCHAR(1000), @separator VARCHAR(10)) 
      RETURNS @resultTable TABLE 
          (parseValue VARCHAR(100))
      AS
      BEGIN
      
          DECLARE @separator_position INT 
          DECLARE @array_value VARCHAR(1000) 
      
          SET @array = @array + @separator
      
          WHILE patindex('%' + @separator + '%' , @array) <> 0 
          BEGIN
      
            SELECT @separator_position =  patindex('%' + @separator + '%', @array)
            SELECT @array_value = left(@array, @separator_position - 1)
      
              INSERT @resultTable
              VALUES (SUBSTRING(Cast(@array_value AS varchar), 1, 1))
      
            SELECT @array = stuff(@array, 1, @separator_position, '')
          END
      
          RETURN
      END
      

      【讨论】:

        【解决方案3】:

        对于 SQL Server 2017 及更高版本:

        CREATE FUNCTION dbo.fnGetFirstChars (@string NVARCHAR(max), @seperator NVARCHAR(MAX))
        RETURNS NVARCHAR(max)
        
        AS BEGIN
        
            DECLARE @result NVARCHAR(MAX)
            SELECT @result = STRING_AGG(SUBSTRING(value, 1, 1), '')
            FROM STRING_SPLIT(@string, @seperator)
        
        RETURN @result
        END;
        

        【讨论】:

          【解决方案4】:

          这是我的解决方案,它具有以下特点/特点:

          • 它可以处理字符串中的任何名称。 (即,少于两个和多于三个。)
          • 保留名称之间的所有空格。

          我知道 OP 已指定在他的案例中只能有 2 或 3 个名称。我不介意。我只是分享一个可行的解决方案,如果它不是最适合特定问题的,那也没关系。

          所以,函数如下:

          CREATE FUNCTION dbo.fnGetInitials (@name varchar(max))
          RETURNS varchar(max)
          AS BEGIN
            DECLARE @cutpos int, @spacepos int, @result varchar(max);
            DECLARE @cutlist TABLE (CutPos int, SpacePos int);
          
            SET @result = LTRIM(RTRIM(@name));
          
            SET @cutpos = 2;
            SET @spacepos = CHARINDEX(' ', @result);
            WHILE @spacepos > 0 BEGIN
              INSERT INTO @cutlist VALUES (@cutpos, @spacepos);
              SET @spacepos = @spacepos + 1;
              SET @cutpos = @spacepos + 1;
              SET @spacepos = CHARINDEX(' ', @result, @spacepos);
            END;
          
            DELETE FROM @cutlist WHERE CutPos >= SpacePos;
          
            SELECT @result = STUFF(@result, CutPos, SpacePos - CutPos, '')
            FROM @cutlist
            ORDER BY CutPos DESC;
          
            RETURN @result;
          END;
          

          这是一个测试调用:

          SELECT dbo.fnGetInitials('  John Ronald   Reuel  Tolkien    ');
          

          结果:

          ----------------------------------------------------------------------------------------------------
          J R   R  Tolkien
          

          【讨论】:

            【解决方案5】:

            你也可以通过 xquery 来实现。

            Declare @Xml XML
            Declare @String Varchar(Max)
            Declare @firstletter Varchar(Max)
            Declare @delimiter Varchar(5) 
            SET @delimiter=' '
            SET @String= 'THIS IS SQL'
            SET @Xml = cast(('<a>'+replace(@String,@delimiter,'</a><a>')+'</a>') AS XML) 
            
            ;WITH CTE AS 
            (SELECT A.value('.', 'varchar(max)') as [Column]FROM @Xml.nodes('a') AS FN(a) )
             SELECT Stuff((SELECT '' + LEFT([Column],1)from CTE 
             FOR XML PATH ('') ),1,0,'') 
            

            这是完整的解决方案。

            http://raresql.com/2013/04/12/sql-server-get-the-first-letter-of-each-word-in-a-string-column/

            【讨论】:

              【解决方案6】:

              图片比描述好 100 倍。下面是一个UDF声明的例子:

              CREATE FUNCTION dbo.GetOnlyFirstLetters(@str NVARCHAR(4000),@sep NVARCHAR(10) )
              RETURNS NVARCHAR(100)
              AS
              BEGIN
                 DECLARE @textXML XML
              
                 SELECT   @textXML = CAST('<d>' + replace(@str, @sep, '</d><d>') + '</d>' AS XML)
              
                  DECLARE @result VARCHAR(8000)
              
                  SET @result = ''
              
                  SELECT  @result = @result + LEFT(T.split.value ('.', 'nvarchar(max)'), 1)
                  FROM @textXML.nodes ('/d') T (split)
              
                  RETURN  @result
              END
              GO
              

              调用方法如下:

              SELECT  dbo.GetOnlyFirstLetters('Humayoun Kabir Sohel',' ');
              

              结果将是:

              HKS
              

              【讨论】:

                猜你喜欢
                • 2013-03-26
                • 1970-01-01
                • 1970-01-01
                • 2019-12-27
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多