sql, чтобы выделить строку имени человека и вывести инициалы

Как я могу получить SQL, чтобы взять жало и вернуть первую букву каждого слова, переданного в него.

Я хочу использовать этот UDF для генерации инициалов для имен людей, которые у меня есть в БД.

имена могут быть 2 (fname, lname) или 3(...mname) словами

я использую sql2005

6 ответов

Решение
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

Это должно работать как для комбинаций "Имя Фамилия", так и "Имя Фамилия Имя".

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

Конечно, если по какой-то причине у пользователей есть пробел в одном из их имен, у вас возникнет проблема с их анализом, но я подозреваю, что это будет иметь место в любом случае, если ваши имена не будут храниться в отдельных полях.

Для 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;

Картинка в 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

Вот мое решение, и оно имеет следующие особенности:

  • Он может обрабатывать сколько угодно имен в строке. (То есть как менее двух, так и более трех.)
  • Все пробелы между именами сохраняются.

Я знаю, что ОП указал, что в его случае могут быть только 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

Вы можете достичь этого с помощью 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/

Другие вопросы по тегам