Получение второго имени из поля полного имени - PullRequest
1 голос
/ 20 апреля 2019

Итак, у меня есть функции для получения имени и фамилии, например:

create function udf_get_first_name (@string nvarchar(100))
    returns nvarchar(50)
as
begin
    declare @first_name nvarchar(50)
        set @string = ltrim(@string)
        set @string = rtrim(@string)

    if dbo.udf_get_number_of_spaces(@string) > 0
        set @first_name = left(@string, charindex(' ',@string) -1)
    else
        set @first_name = @string
    return @first_name
end

create function udf_get_last_name (@string nvarchar(100))
returns nvarchar(50)
as
    begin 
        set @string = ltrim(@string)
        set @string = rtrim(@string)
        if dbo.udf_get_number_of_spaces (@string) > 0
            begin
                set @string = reverse(@string)
                set @string = left(@string, charindex(' ', @string) -1)
                set @string = reverse(@string)
            end
        return @string
    end



Мне нужно иметь возможность получить второе имя, и я просто не могу обернуть головуто, что я прочитал через мои поиски до сих пор.Не уверен, что я просто тупой или нет.

Мне также нужно иметь возможность сортировать имя, отформатированное как L / M / F, в соответствующие столбцы, с которыми мне еще труднее.

Редактировать:Не все записи имеют отчество.

Ответы [ 5 ]

3 голосов
/ 20 апреля 2019

Вы можете использовать следующее решение, используя функцию для получения части имени или полного имени в указанном формате:

--
-- function to get a part of a fullname or to reformat the fullname.
-- @fullname - the fullname to get the part from or to reformat.
-- @format - the format of the output using F (firstname), M (middlename) and L (lastname).
-- the function returns the fullname in specified format or NULL if input is not valid 
-- or the part of name is empty.
--
CREATE FUNCTION GetNamePart(@fullname VARCHAR(200), @format VARCHAR(30))
RETURNS VARCHAR(200)
AS
BEGIN

  -- replace multiple spaces of the fullname and trim the result.
  SET @fullname = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(@fullname, ' ', '<>'), '><', ''), '<>', ' ')))

  -- get the different name parts (firstname, middlename and lastname) of the fullname.
  DECLARE @first_name VARCHAR(100)
  SET @first_name = LTRIM(RTRIM(LEFT(@fullname, CHARINDEX(' ', @fullname))))
  DECLARE @last_name VARCHAR(100)
  SET @last_name = LTRIM(RTRIM(RIGHT(@fullname, CHARINDEX(' ', REVERSE(@fullname)))))
  DECLARE @middle_name VARCHAR(100)
  SET @middle_name = LTRIM(RTRIM(SUBSTRING(@fullname, LEN(@first_name) + 1, LEN(@fullname) - LEN(@first_name) - LEN(@last_name))))

  -- init the formatted name of the fullname.
  DECLARE @formatted_name VARCHAR(100)

  -- return only the formatted name if format string is valid.
  IF PATINDEX('%[^LMF]%', UPPER(@format)) > 0
    SET @formatted_name = ''
  ELSE
    BEGIN
      SET @format = REPLACE(REPLACE(REPLACE(@format, 'M', '##M##'), 'L', '##L##'), 'F', '##F##')
      SET @formatted_name = LTRIM(RTRIM(REPLACE(REPLACE(REPLACE(UPPER(@format), '##F##', @first_name + ' '), '##M##', @middle_name + ' '), '##L##', @last_name + ' ')))
    END

   -- check the input (@fullname) for valid value (firstname, lastname or firstname, middlename, lastname).
   IF PATINDEX('%_ %_% _%', @fullname) = 0 AND PATINDEX('%_ _%', @fullname) = 0
     SET @formatted_name = ''

   -- return the new formatted name and replace multiple spaces.
  RETURN NULLIF(REPLACE(REPLACE(REPLACE(@formatted_name, ' ', '<>'), '><', ''), '<>', ' '), '')
END

Эта функция GetNamePart использует два параметра (@fullnameи @format).Первый параметр @fullname - это полное имя, содержащее имя, фамилию и, если возможно, среднее имя.Второй параметр определяет формат вывода имени.Вы можете использовать буквы F (имя), M (имя-середина) и L (фамилия), чтобы определить формат вывода.

Таким образом, вы можете использовать функцию GetNamePart, чтобы получитьсреднее имя полного имени:

SELECT dbo.GetNamePart(fullname, 'M') FROM table_name

... или переформатировать полное имя следующим образом:

SELECT dbo.GetNamePart(fullname, 'LMF') FROM table_name

демо на dbfiddle.uk (демонстрационные и тестовые примеры)


Но вы также можете использовать запрос SELECT, чтобы получить различные части имени без функции:

SELECT
  LTRIM(RTRIM(LEFT(fullname, CHARINDEX(' ', fullname)))) AS first_name,
  LTRIM(RTRIM(RIGHT(fullname, CHARINDEX(' ', REVERSE(fullname))))) AS last_name,
  LTRIM(RTRIM(CASE WHEN PATINDEX('%_ %_% _%', fullname) > 0 THEN SUBSTRING(fullname, CHARINDEX(' ', fullname) + 1, (CHARINDEX(' ', fullname, CHARINDEX(' ', fullname)+1)-(CHARINDEX(' ', fullname) + 1))) ELSE '' END)) AS middle_name
FROM table_name

демо на dbfiddle.uk

1 голос
/ 20 апреля 2019

Похоже на Себастьян Брош . Я также добавил функцию TRIM после того, как увидел его ответ. В этом запросе это не обязательно. Но это приятно. Например, если пользователь добавил несколько пробелов по ошибке, это удалит это.

Возможно, есть лучший или более простой способ получить имя, отчество и фамилию. Но это способ, которым я придумываю на данный момент.

CREATE FUNCTION dbo.SplitFullName(
    @FullName NVARCHAR(MAX),
    @Format NVARCHAR(MAX)
)
RETURNS NVARCHAR(MAX)
AS 
BEGIN
    DECLARE @FN NVARCHAR(MAX);
    DECLARE @MN NVARCHAR(MAX);
    DECLARE @LN NVARCHAR(MAX); 
    DECLARE @RV NVARCHAR(MAX); 

    SET @FN = RTRIM(LTRIM(SUBSTRING(@FullName,0, CHARINDEX(' ',@FullName))));
    SET @MN = RTRIM(LTRIM(SUBSTRING(@FullName, CHARINDEX(' ',@FullName) + 1 , LEN(@FullName) - (CHARINDEX(' ',@FullName) + CHARINDEX(' ',REVERSE(@FullName)))+1)));
    SET @LN = RTRIM(LTRIM(REVERSE(SUBSTRING(REVERSE(@FullName),0, CHARINDEX(' ',REVERSE(@FullName))))));

    IF (@Format='FN') 
        SET @RV = CASE WHEN LEN(@FN) = 0 THEN NULL ELSE @FN END;
    ELSE IF (@Format='MN') 
        SET @RV = CASE WHEN LEN(@MN) = 0 THEN NULL ELSE @MN END;
    ELSE IF (@Format='LN') 
        SET @RV = CASE WHEN LEN(@LN) = 0 THEN NULL ELSE @LN END;;
    ELSE
        SET @RV = CONCAT(@LN, ' ',  CASE WHEN LEN(@MN) = 0 THEN NULL ELSE CONCAT(@MN , ' ') END, @FN);

    RETURN @RV;
END;

Пример 01

SELECT dbo.SplitFullName('Antonio P. Green', 'FN')  AS FN,
       dbo.SplitFullName('Antonio P. Green', 'MN')  AS MN,
       dbo.SplitFullName('Antonio P. Green', 'LN')  AS LN, 
       dbo.SplitFullName('Antonio P. Green', 'LMF') AS LMF;

+---------+----+-------+------------------+
|   FN    | MN |  LN   |       LMF        |
+---------+----+-------+------------------+
| Antonio | P. | Green | Green P. Antonio |
+---------+----+-------+------------------+

Пример 02

select dbo.SplitFullName('Cindy Bertha Collier Sproles', 'FN')  AS FN,
       dbo.SplitFullName('Cindy Bertha Collier Sproles', 'MN')  AS MN,
       dbo.SplitFullName('Cindy Bertha Collier Sproles', 'LN')  AS LN,
       dbo.SplitFullName('Cindy Bertha Collier Sproles', 'LMF') AS LMF;

+-------+----------------+---------+------------------------------+
|  FN   |       MN       |   LN    |             LMF              |
+-------+----------------+---------+------------------------------+
| Cindy | Bertha Collier | Sproles | Sproles Bertha Collier Cindy |
+-------+----------------+---------+------------------------------+

Пример 03

SELECT dbo.SplitFullName('Tristan Jackson', 'FN')  AS FN,
       dbo.SplitFullName('Tristan Jackson', 'MN')  AS MN,
       dbo.SplitFullName('Tristan Jackson', 'LN')  AS LN, 
       dbo.SplitFullName('Tristan Jackson', 'LMF') AS LMF;

+---------+------+---------+-----------------+
|   FN    |  MN  |   LN    |       LMF       |
+---------+------+---------+-----------------+
| Tristan | NULL | Jackson | Jackson Tristan |
+---------+------+---------+-----------------+
0 голосов
/ 20 апреля 2019

Будущее за SQL Server 2016: использовать функцию STRING_SPLIT

Use Northwind
Go

SELECT ProductID, value  
FROM Products  
CROSS APPLY STRING_SPLIT(ProductName, ' ');  

по этому запросу вы можете разделить имена ... затем с помощью функции Row () вы можете выбрать отчество.


STRING_SPLIT требует, чтобы уровень совместимости был не менее 130. Если уровень меньше 130, SQL Server не может найти функцию STRING_SPLIT.

0 голосов
/ 20 апреля 2019

Выберите Ltrim (SUBSTRING (имя, CharIndex ('', имя), ПРИЧИНА Когда (CHARINDEX ('', name, CHARINDEX ('', name) +1) -CHARINDEX ('', name)) <= 0, затем 0 иначе CHARINDEX ('', name, CHARINDEX ('', name) +1) -CHARINDEX ('', name) end)) как MiddleName Из TableName </p>

0 голосов
/ 20 апреля 2019

Вы можете справиться с этим, используя CTE с несколькими запятыми.

declare @str nvarchar(max) ='kareena kapoor khan';

with 
t0 AS (select charindex(' ',@str) pos, @str name ),
t1 AS (select charindex(' ',@str,pos+1)pos,@str name from  t0)
select substring(t0.name,0,t0.pos) "firstName",
       substring(t0.name,t0.pos+1,(t1.pos-t0.pos)) "MiddleName",
       substring(t0.name,t1.pos+1,(len(t0.name)- t1.pos)) "Lastname" 
from    t0
inner join t1 on t0. name= t1.name

выход

| firstName | MiddleName | Фамилия

| Карина | капур | хан

Кроме того, вместо создания 3-х функций для имени, отчества и фамилии, вы можете просто создать одну функцию и передать параметр как @namepart.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...