SQL: анализировать имя, отчество и фамилию из поля полного имени - PullRequest
40 голосов
/ 02 октября 2008

Как мне разобрать имя, отчество и фамилию из поля полного имени с помощью SQL?

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

Данные не включают префиксы или суффиксы. Отчество не обязательно. Данные отформатированы как «Первый Средний Последний».

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

Ответы [ 23 ]

0 голосов
/ 02 октября 2008

С учетом предостережений, которые уже были высказаны в отношении пробелов в именах и других аномалий, следующий код будет обрабатывать как минимум 98% имен. (Примечание: грязный SQL, потому что у меня нет опции регулярного выражения в базе данных, которую я использую.)

** Внимание: следует грязный SQL:

create table parsname (fullname char(50), name1 char(30), name2 char(30), name3 char(30), name4 char(40));
insert into parsname (fullname) select fullname from ImportTable;
update parsname set name1 = substring(fullname, 1, locate(' ', fullname)),
 fullname = ltrim(substring(fullname, locate(' ', fullname), length(fullname)))
 where locate(' ', rtrim(fullname)) > 0;
update parsname set name2 = substring(fullname, 1, locate(' ', fullname)),
 fullname = ltrim(substring(fullname, locate(' ', fullname), length(fullname)))
 where locate(' ', rtrim(fullname)) > 0;
update parsname set name3 = substring(fullname, 1, locate(' ', fullname)),
 fullname = ltrim(substring(fullname, locate(' ', fullname), length(fullname)))
 where locate(' ', rtrim(fullname)) > 0;
update parsname set name4 = substring(fullname, 1, locate(' ', fullname)),
 fullname = ltrim(substring(fullname, locate(' ', fullname), length(fullname)))
 where locate(' ', rtrim(fullname)) > 0;
// fullname now contains the last word in the string.
select fullname as FirstName, '' as MiddleName, '' as LastName from parsname where fullname is not null and name1 is null and name2 is null
union all
select name1 as FirstName, name2 as MiddleName, fullname as LastName from parsname where name1 is not null and name3 is null

Код работает путем создания временной таблицы (имя_парла) и токенизации полного имени по пробелам. Любые имена, заканчивающиеся значениями в name3 или name4, не соответствуют друг другу и должны рассматриваться по-разному.

0 голосов
/ 27 мая 2019

ОТВЕТ

Этот запрос работает нормально.

Выберите имя, Ltrim (SubString (name, 1, Isnull (Nullif (CHARINDEX ('', name), 0), 1000))) как имя,

Ltrim (SUBSTRING (имя, CharIndex ('', name), CAse When (CHARINDEX ('', name, CHARINDEX ('', name) +1) -CHARINDEX ('', name)) <= 0 затем 0 иначе CHARINDEX ('', name, CHARINDEX ('', name) +1) -CHARINDEX ('', name) end)) как MiddleName, </p>

Ltrim (SUBSTRING (имя, Isnull (Nullif (CHARINDEX ('', name, Charindex ('', name) +1), 0), CHARINDEX ('', name)), Случай когда Charindex ('' name) = 0, затем 0 else LEN (name) end)) as LastName

С вашего имени_таблицы

Спасибо Мукеш

0 голосов
/ 02 октября 2008

Вот хранимая процедура, которая помещает первое найденное слово в Имя, последнее слово - в Фамилию, а все промежуточное - в Имя.

create procedure [dbo].[import_ParseName]
(            
    @FullName nvarchar(max),
    @FirstName nvarchar(255) output,
    @MiddleName nvarchar(255) output,
    @LastName nvarchar(255)  output
)
as
begin

set @FirstName = ''
set @MiddleName = ''
set @LastName = ''  
set @FullName = ltrim(rtrim(@FullName))

declare @ReverseFullName nvarchar(max)
set @ReverseFullName = reverse(@FullName)

declare @lengthOfFullName int
declare @endOfFirstName int
declare @beginningOfLastName int

set @lengthOfFullName = len(@FullName)
set @endOfFirstName = charindex(' ', @FullName)
set @beginningOfLastName = @lengthOfFullName - charindex(' ', @ReverseFullName) + 1

set @FirstName = case when @endOfFirstName <> 0 
                      then substring(@FullName, 1, @endOfFirstName - 1) 
                      else ''
                 end

set @MiddleName = case when (@endOfFirstName <> 0 and @beginningOfLastName <> 0 and @beginningOfLastName > @endOfFirstName)
                       then ltrim(rtrim(substring(@FullName, @endOfFirstName , @beginningOfLastName - @endOfFirstName))) 
                       else ''
                  end

set @LastName = case when @beginningOfLastName <> 0 
                     then substring(@FullName, @beginningOfLastName + 1 , @lengthOfFullName - @beginningOfLastName)
                     else ''
                end

return

end 

И вот я это называю.

DECLARE @FirstName nvarchar(255),
        @MiddleName nvarchar(255),
        @LastName nvarchar(255)

EXEC    [dbo].[import_ParseName]
        @FullName = N'Scott The Other Scott Kowalczyk',
        @FirstName = @FirstName OUTPUT,
        @MiddleName = @MiddleName OUTPUT,
        @LastName = @LastName OUTPUT

print   @FirstName 
print   @MiddleName
print   @LastName 

output:

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