Oracle Query для анализа суффикса из имени - PullRequest
0 голосов
/ 07 июня 2018

У меня есть полное имя (фамилия, имя, отчество, включая суффикс) в одном поле.Вот бизнес-правило для разбора имени

.Фамилия: символы от первой позиции до запятой будут идти в фамилии.,Имя: первые символы после запятой перед следующим пробелом будут переходить к имени.,Суффикс: После того, как имя и фамилия получены, ищите суффикс имени в оставшейся части имени на основе значений (Jr, Sr, II, III, IV, V).Отчество: поместите остальные символы в отчество.

  1. LST, FRST MDL SR (ее LST - фамилия, FRST - имя, MDL - отчество, суффикс SR)
  2. LST, FRST SR MDL MDL2 (ее LST - LastName, FRST - FirstName, "MDL MDL2" - middleName, суффикс SR)
  3. LST, FRST MDL1 JR MDL2 MDL3 (ее LST - LastName, FRST - FirstName, «MDL1 MDL2 MDL3» - MiddleName, суффикс JR)

Значение суффикс и среднийимя в различных форматах.Можно ли написать запрос для извлечения суффикса и помещения остатка в поле среднего имени?

Вот мой запрос, но я ищу более простой способ, а также мой запрос проверяет до 3 пробелов в отчестве, чтобы найтисуффикс.

WITH IDN_NAM AS
(
 SELECT RECORD_NUMBER, IDN.INDEX1,
  trim(regexp_substr(REPLACE(IDN.IDN_NAM,',',' '),  '[^ ]+',1,2)) AS FIRST_NAME,
  trim(regexp_substr(REPLACE(IDN.IDN_NAM,',',' '),  '[^ ]+',1,1)) AS LAST_NAME,
  CASE WHEN instr(REPLACE(IDN.IDN_NAM,',',' '),' ',1,2)+1 = 1 THEN NULL ELSE substr(REPLACE(IDN.IDN_NAM,',',' '),instr(REPLACE(IDN.IDN_NAM,',',' '),' ',1,2)+1) END AS MID_NAME,
  TRIM(IDN.IDN_NAM) AS FULL_NAME
  FROM 
  (
   SELECT IDN.RECORD_NUMBER, IDN_NAM IDN_NAM_ORIG, replace(replace(replace(REPLACE(IDN.IDN_NAM, ',', ' '),' ','<>'),'><',''),'<>',' ') IDN_NAM , IDN.INDEX1
   FROM SNM_TMP_IDENTITY_IDN_NAM IDN,
        TMP_LEGACY_EVENT T
   WHERE IDN.RECORD_NUMBER = T.RECORD_NUMBER 
    AND NOT REGEXP_LIKE(IDN_NAM,'DLE.+[[:digit:]]')
  ) IDN
)
SELECT DECODE(INDEX1, 1, 'T', 'F') MASTER_IND, FIRST_NAME, LAST_NAME,--, MID_NAME, MID_NAM1, MID_NAM2, MID_NAM3, SUF1, SUF2, SUF3,
CASE WHEN SUF3 IS NULL AND SUF2 IS NULL AND SUF1 IS NULL THEN MID_NAME
    WHEN SUF3 IS NOT NULL THEN NVL(MID_NAM1,'')||CASE WHEN MID_NAM2 IS NOT NULL THEN ' '||MID_NAM2 ELSE '' END
    WHEN SUF2 IS NOT NULL THEN NVL(MID_NAM1,'')||CASE WHEN MID_NAM3 IS NOT NULL THEN ' '||MID_NAM3 ELSE '' END
    WHEN SUF1 IS NOT NULL THEN NVL(MID_NAM2,'')||CASE WHEN MID_NAM3 IS NOT NULL THEN ' '||MID_NAM3 ELSE '' END
END MIDDLE_NAME,
NVL(SUF3, NVL(SUF2, SUF1)) NAME_SUFFIX_CD
FROM
(
SELECT NM.*,
(SELECT MAX(NAME_SUFFIX_CODE) FROM CRRMS_CODED.CODED_NAME_SUFFIX WHERE UPPER(REPLACE(NAME_SUFFIX_CODE,'.', '')) = UPPER(MID_NAM1)) SUF1,
(SELECT MAX(NAME_SUFFIX_CODE) FROM CRRMS_CODED.CODED_NAME_SUFFIX WHERE UPPER(REPLACE(NAME_SUFFIX_CODE,'.', '')) = UPPER(MID_NAM2)) SUF2,
(SELECT MAX(NAME_SUFFIX_CODE) FROM CRRMS_CODED.CODED_NAME_SUFFIX WHERE UPPER(REPLACE(NAME_SUFFIX_CODE,'.', '')) = UPPER(MID_NAM3)) SUF3
FROM
(
 SELECT I.*,
  trim(regexp_substr(MID_NAME,  '[^ ]+',1,1)) AS MID_NAM1,
  trim(regexp_substr(MID_NAME,  '[^ ]+',1,2)) AS MID_NAM2,
  trim(regexp_substr(MID_NAME,  '[^ ]+',1,3)) AS MID_NAM3
 FROM IDN_NAM I
) NM
)
;

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Din,

Взял 3 примера ввода и сделал запрос в соответствии с вашей логикой для получения Фамилии, Имени, Суффикса и Отчества.Для всех 3 это работало нормально.

select last_name,first_name,suffix
,trim(regexp_replace(input_string,'(^'||last_name||',|'||first_name||'|'||suffix||')',' ',1,0,'i')) as middle_name
from (
select substr(col,1,instr(col,',',1,1)-1) as last_name ,
trim(substr(col,instr(col,',',1,1)+1,instr(col,' ',1,1))) as first_name,
trim(regexp_substr(col,'(Jr|Sr|II|III|IV|V)',1,1,'i')) as suffix,
col as input_string
from (
select 'LST, FRST MDL1 JR MDL2 MDL3' as col from dual));
0 голосов
/ 07 июня 2018

Вот запрос, который может отвечать всем требованиям, хотя он выходит за рамки определения проблемы и обрабатывает префиксы:

with names(name) as (
            select 'LST, FRST MDL SR' from dual
  union all select 'LST, FRST SR MDL MDL2' from dual
  union all select 'LST, FRST MDL1 JR MDL2 MDL3' from dual
  union all select 'Jones, John Paul' from dual
  union all select 'Jones, Mr. John Jr Paul' from dual
  union all select 'Jones, John Paul Jr Henry' from dual
  union all select 'Henry, John Paul Sr' from dual
  union all select 'Masters, Lee II' from dual
)
select name
     , REGEXP_SUBSTR(name, '([^,]+), ?(((dr|rev|mr|mrs|ms|miss)[.]?) )?([^ ]+) ?(.*)',1,1,'i',3) pfx
     , REGEXP_SUBSTR(name, '([^,]+), ?(((dr|rev|mr|mrs|ms|miss)[.]?) )?([^ ]+) ?(.*)',1,1,'i',5) frst
     , rtrim(REGEXP_REPLACE(
       REGEXP_SUBSTR(name, '([^,]+), ?(((dr|rev|mr|mrs|ms|miss)[.]?) )?([^ ]+) ?(.*)',1,1,'i',6)
       ,'(^|[[:space:]])(jr|sr|ii|iii|iv|v)([[:space:]]|$)','\1',1,1,'i')) mdl
     , REGEXP_SUBSTR(name, '([^,]+), ?(((dr|rev|mr|mrs|ms|miss)[.]?) )?([^ ]+) ?(.*)',1,1,'i',1) Lst
     , REGEXP_SUBSTR(
       REGEXP_SUBSTR(name, '([^,]+), ?(((dr|rev|mr|mrs|ms|miss)[.]?) )?([^ ]+) ?(.*)',1,1,'i',6)
       ,'(^|[[:space:]])(jr|sr|ii|iii|iv|v)([[:space:]]|$)',1,1,'i',2) SFX
from names;

Если вы не хотите, чтобы префиксы работали, это может работатьyou:

select name
     , REGEXP_SUBSTR(name, '([^,]+), ?([^ ]+) ?(.*)',1,1,'i',2) frst
     , rtrim(REGEXP_REPLACE(
       REGEXP_SUBSTR(name, '([^,]+), ?([^ ]+) ?(.*)',1,1,'i',3)
       ,'(^|[[:space:]])(jr|sr|ii|iii|iv|v)([[:space:]]|$)','\1',1,1,'i')) mdl
     , REGEXP_SUBSTR(name, '([^,]+), ?([^ ]+) ?(.*)',1,1,'i',1) Lst
     , REGEXP_SUBSTR(
       REGEXP_SUBSTR(name, '([^,]+), ?([^ ]+) ?(.*)',1,1,'i',3)
       ,'(^|[[:space:]])(jr|sr|ii|iii|iv|v)([[:space:]]|$)',1,1,'i',2) SFX
from names;

Одно и то же регулярное выражение используется для идентификации и извлечения каждой части имени:

'([^,]+), ?([^ ]+) ?(.*)'
 |     |   |     |  +--+ -> 3) Middle Names (including Suffix)
 |     |   +-----+ -------> 2) First Name
 +-----+ -----------------> 1) Last Name

Имя и фамилия являются прямыми.Средние имена и суффиксы, однако, требуют немного дополнительной работы для управления.Чтобы получить только вторые имена или суффикс, требуется второе регулярное выражение:

'(^|[[:space:]])(jr|sr|ii|iii|iv|v)([[:space:]]|$)'

Используя вышеприведенное регулярное выражение вместе с функцией REGEXP_REPLACE, суффикс можно удалить, оставив только вторые имена.Аналогично, используя то же регулярное выражение с функцией REGEXP_SUBSTR, можно получить сам суффикс.

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