Создание оператора SELECT для фильтрации имен из одного столбца - PullRequest
0 голосов
/ 16 апреля 2019

У нас есть столбец имен, и есть несколько вещей, которые необходимо проанализировать, поскольку он должен выглядеть как LASTNAME FIRSTNAME MIDDLENAME. Столбец всегда начинается с LASTNAME, затем через запятую до FIRSTNAME, затем он может быть разделен запятой или пробелом или даже через скобки (()) для MIDDLENAME.

У меня есть код для фильтрации LASTNAME:

SUBSTRING([Name], 0, PATINDEX('%,%', [Name])) AS LastName

Но у меня проблемы с фильтрацией через FIRSTNAME и MIDDLENAME. Вот несколько примеров того, как выглядит столбец

LASTNAME,FIRSTNAME MIDDLENAME
LASTNAME,FIRSTNAME,MIDDLENAME
LAST NAME,FIRSTNAME MIDDLENAME
LAST NAME,FIRSTNAME (MIDDLENAME)

Теперь, если в скобках есть что-то, мы не хотим отображать эту информацию в скобках. поэтому мы игнорировали бы MIDDLENAME. Столбец может иметь любую комбинацию для LASTNAME, FIRSTNAME и MIDDLENAME с пробелами, запятыми или скобками, а MIDDLENAME может также существовать вне скобок:

LASTNAME,FIRSTNAME (NICKNAME) MIDDLENAME

В этом случае мы хотим MIDDLENAME и игнорировать NICKNAME

Любая помощь очень ценится!

Ответы [ 2 ]

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

Я добавлю ваши примеры в таблицу памяти, чтобы мы могли проверить их, как показано ниже: - (вам это не нужно)

Declare @NameTable table (fullname varchar(250))
insert into @NameTable values
('LASTNAME,FIRSTNAME MIDDLENAME'),
('LASTNAME,FIRSTNAME,MIDDLENAME'),
('LAST NAME,FIRSTNAME MIDDLENAME'),
('LAST NAME,FIRSTNAME (MIDDLENAME)'),
('LASTNAME,FIRSTNAME (NICKNAME) MIDDLENAME'),
('LASTNAME,FIRSTNAME') -- no middle name

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

;with FindBrackts as (
/* get rid of brackets */
select *,CHARINDEX('(',fullname) bStart,CHARINDEX(')',fullname) bEnd from @NameTable
),RemoveBrackts as (
    select case when bStart>0 then substring(fullname,1,bStart-1)+substring(fullname,bEnd+2,len(fullname)-bEnd+1)
        else fullname end fullname from FindBrackts)
,LastNameAndTheRest as (
    select substring(fullname,1,CHARINDEX(',',fullname)-1) [LASTNAME]
,substring(fullname,CHARINDEX(',',fullname)+1,len(fullname)-CHARINDEX(',',fullname)) [TheRest] from RemoveBrackts
),LastFirstMiddle as (
    select [LASTNAME],[TheRest],CHARINDEX(',',replace([TheRest],' ',',')) [mStart] from LastNameAndTheRest
)
select [LASTNAME]
    ,case when mStart=0 then [TheRest] else substring([TheRest],1,[mStart]-1) end FIRSTNAME  
    ,case when mStart=0 then null else substring([TheRest],[mStart]+1,len([TheRest])-[mStart]) end MIDDLENAME 
    from LastFirstMiddle

Результат будет примерно таким, как показано ниже: -

LASTNAME    FIRSTNAME   MIDDLENAME
========    =========   ==========
LASTNAME    FIRSTNAME   MIDDLENAME
LASTNAME    FIRSTNAME   MIDDLENAME
LAST NAME   FIRSTNAME   MIDDLENAME
LAST NAME   FIRSTNAME   NULL
LASTNAME    FIRSTNAME   MIDDLENAME

Если это поможет, и вы найдетеесли есть больше условий, добавьте их и, возможно, обновите запрос, чтобы учесть их.

здесь то же самое в SQL Fiddle http://sqlfiddle.com/#!18/2dd42/2/0

Или, если вы не хотите использовать CTE, егонемного длиннее, но вы можете попробовать следующее: -

select 
    SUBSTRING(fullname, 0, CHARINDEX(',', fullname)) AS LastName 
    ,SUBSTRING(replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','),1,CHARINDEX(',',replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','))-1) [FirstName]
    ,SUBSTRING(fullname,2+len(fullname)-CHARINDEX(',',reverse(replace(fullname,' ',','))),len(fullname)) MiddleName
    from @NameTable

Результаты будут такими, как показано ниже (немного отличается от предыдущего решения)

LastName    FirstName   MiddleName
========    =========   ==========
LASTNAME    FIRSTNAME   MIDDLENAME
LASTNAME    FIRSTNAME   MIDDLENAME
LAST NAME   FIRSTNAME   MIDDLENAME
LAST NAME   FIRSTNAME   (MIDDLENAME)
LASTNAME    FIRSTNAME   MIDDLENAME

, если нет MiddlenameCTE справится с этим, но для выбора потребуется обновить следующее: -

select 
    SUBSTRING(fullname, 0, CHARINDEX(',', fullname)) AS LastName 
    ,case when CHARINDEX(',',replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','))>0 then
        SUBSTRING(replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','),1,CHARINDEX(',',replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','))-1) 
        else replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',',') end [FirstName]
    ,case when CHARINDEX(',',replace(SUBSTRING(fullname,CHARINDEX(',', fullname)+1,len(fullname)-CHARINDEX(',', fullname)),' ',','))>0 then
        SUBSTRING(fullname,2+len(fullname)-CHARINDEX(',',reverse(replace(fullname,' ',','))),len(fullname))
        else  NULL end MiddleName
    from @NameTable

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

LastName    FirstName   MiddleName
=========   =========   ==========
LASTNAME    FIRSTNAME   MIDDLENAME
LASTNAME    FIRSTNAME   MIDDLENAME
LAST NAME   FIRSTNAME   MIDDLENAME
LAST NAME   FIRSTNAME   (MIDDLENAME)
LASTNAME    FIRSTNAME   MIDDLENAME
LASTNAME    FIRSTNAME   NULL
0 голосов
/ 17 апреля 2019

Пожалуйста, попробуйте это:

;WITH Data AS (
    SELECT a.ID,a.LastName
        ,REPLACE(REPLACE(REPLACE(REPLACE(a.RotN,' (','.'),')',''),',','.'),' ','.') AS [DotSplitName]
    FROM (
        SELECT ROW_NUMBER()OVER(ORDER BY (SELECT 1)) AS [ID]
            ,SUBSTRING(t.fullname,1,CHARINDEX(',',t.fullname)-1) AS [LastName]
            ,SUBSTRING(t.fullname,CHARINDEX(',',t.fullname)+1,999) AS [RotN] /*Rest of the name*/
        FROM @NameTable t
        WHERE t.fullname LIKE '%[,]%'
    ) a
)
SELECT d.ID,d.LastName
    ,COALESCE(PARSENAME(d.DotSplitName,3),PARSENAME(d.DotSplitName,2)) AS [FirstName]
    ,PARSENAME(d.DotSplitName,1) AS [MiddleName]
    ,CASE WHEN PARSENAME(d.DotSplitName,3) IS NOT NULL THEN PARSENAME(d.DotSplitName,2) ELSE NULL END AS [NickName]
FROM Data d
;

Спасибо Али Аль-Мосави за пример таблицы памяти

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