如何将NAME分成3个不同的字段FIRST_NAME,MIDDLE_NAME&有空格时的LAST_NAME

时间:2016-08-10 16:15:57

标签: sql oracle oracle11g

如何将NAME拆分为3个不同的字段FIRST_NAME, MIDDLE_NAME & LAST_NAME

目前,NAME提交的格式如下     [FIRST_NAME || ' ' || MIDDLE_NAME|| ' ' ||LAST_NAME]。更清楚地假设一个人名是

FIRST_NAME: SHERRY 
MIDDLE_NAME: L
LAST_NAME : CLEAVES

然后NAME字段有" SHERRY L CLEAVES",我希望它在3个不同的领域。另外,如果只有两个名字,我该如何处理?

一些样本数据如下:

  ('William  Sears',
       'PETER E LABBE',
       'Edith  Roberts',
       'SHERRY L CLEAVES',
       'Sharon  Matthes',
       'TAMMY L PELLETIER',
       'STACIE M KINER',
       'MICHAEL C THOMAS',
       'CHESTER R DAVIS',
       'MICHAEL D HUTCHINSON',
       'Paul  Mikkelsen'
       )

3 个答案:

答案 0 :(得分:3)

以下是一种方法:

with data_qry
as
(
select 'William  Sears' as name from dual union all
select 'PETER E LABBE' as name from dual union all
select 'Edith  Roberts' as name from dual union all
select 'SHERRY L CLEAVES' as name from dual union all
select 'Sharon  Matthes' as name from dual union all
select 'TAMMY L PELLETIER' as name from dual union all
select 'STACIE M KINER' as name from dual union all
select 'MICHAEL C THOMAS' as name from dual union all
select 'CHESTER R DAVIS' as name from dual union all
select 'MICHAEL D HUTCHINSON' as name from dual union all
select 'Paul  Mikkelsen' as name from dual
)
select name
     , substr(name, 1, instr(name, ' ', 1)) as first
     , case when instr(name, ' ', 1, 2) > 0 then substr(name, instr(name, ' ', 1, 1) + 1, instr(name, ' ', 1, 2) - instr(name, ' ', 1, 1) - 1) else null end as middle
     , case when instr(name, ' ', 1, 2) > 0 then substr(name, instr(name, ' ', 1, 2) + 1) else substr(name, instr(name, ' ', 1, 1) + 1) end as last
from data_qry

输出:

NAME                 FIRST      MIDDLE     LAST
William  Sears       William               Sears
PETER E LABBE        PETER      E          LABBE
Edith  Roberts       Edith                 Roberts
SHERRY L CLEAVES     SHERRY     L          CLEAVES
Sharon  Matthes      Sharon                Matthes
TAMMY L PELLETIER    TAMMY      L          PELLETIER
STACIE M KINER       STACIE     M          KINER
MICHAEL C THOMAS     MICHAEL    C          THOMAS
CHESTER R DAVIS      CHESTER    R          DAVIS
MICHAEL D HUTCHINSON MICHAEL    D          HUTCHINSON
Paul  Mikkelsen      Paul                  Mikkelsen

答案 1 :(得分:2)

你可以这样做。我处理了一些可能性,比如名字和姓氏之间的任意数量的空格(没有中间的首字母),或者在名字和名字之间,或者在名字和姓氏之间。也是多字母缩写。还会有很多其他意料之外的问题,例如有两个名字或两个姓氏的人等。

with input_strings ( str ) as (
       select 'William  Sears'       from dual union all
       select 'PETER E LABBE'        from dual union all
       select 'Edith  Roberts'       from dual union all
       select 'SHERRY L CLEAVES'     from dual union all
       select 'Sharon  Matthes'      from dual union all
       select 'TAMMY L PELLETIER'    from dual union all
       select 'STACIE M KINER'       from dual union all
       select 'MICHAEL C THOMAS'     from dual union all
       select 'CHESTER R DAVIS'      from dual union all
       select 'MICHAEL D HUTCHINSON' from dual union all
       select 'Paul  Mikkelsen'      from dual
     )
select initcap(substr(str, 1, instr(str, ' ') - 1)) as first_name,
       upper(trim(substr(str, instr(str, ' '), 
               instr(str, ' ', -1) - instr(str, ' ')))) as mid_in,
       initcap(substr(str, instr(str, ' ', -1) + 1)) as last_name
from   input_strings;

FIRST_NAME                     MID_IN LAST_NAME
------------------------------ ------ ------------------------------
William                               Sears
Peter                          E      Labbe
Edith                                 Roberts
Sherry                         L      Cleaves
Sharon                                Matthes
Tammy                          L      Pelletier
Stacie                         M      Kiner
Michael                        C      Thomas
Chester                        R      Davis
Michael                        D      Hutchinson
Paul                                  Mikkelsen

11 rows selected.

答案 2 :(得分:0)

嘿,不要忘记正则表达式!假设你的名字真的太简单了,给出了为分隔符设置空间的名称的规范,以及你没有处理通常的名称问题的事实,这实际上只是解析一个可以用正则表达式完成的分隔字符串可以处理NULL列表元素(中间的首字母):

SQL> with tbl(name) as (
   select 'William  Sears'       from dual union all
   select 'PETER E LABBE'        from dual union all
   select 'Edith  Roberts'       from dual union all
   select 'SHERRY L CLEAVES'     from dual union all
   select 'Sharon  Matthes'      from dual union all
   select 'TAMMY L PELLETIER'    from dual union all
   select 'STACIE M KINER'       from dual union all
   select 'MICHAEL C THOMAS'     from dual union all
   select 'CHESTER R DAVIS'      from dual union all
   select 'MICHAEL D HUTCHINSON' from dual union all
   select 'Paul  Mikkelsen'      from dual
   )
   select regexp_substr(name, '(.*?)( |$)', 1, 1, NULL, 1) first_name,
          regexp_substr(name, '(.*?)( |$)', 1, 2, NULL, 1) mid_init,
          regexp_substr(name, '(.*?)( |$)', 1, 3, NULL, 1) last_name
   from tbl;

FIRST_NAME           MID_INIT             LAST_NAME
-------------------- -------------------- --------------------
William                                   Sears
PETER                E                    LABBE
Edith                                     Roberts
SHERRY               L                    CLEAVES
Sharon                                    Matthes
TAMMY                L                    PELLETIER
STACIE               M                    KINER
MICHAEL              C                    THOMAS
CHESTER              R                    DAVIS
MICHAEL              D                    HUTCHINSON
Paul                                      Mikkelsen

11 rows selected.

SQL>

是的,它已被说了一百万次,但我会省去你的麻烦:substr()/ instr()更快但我发现嵌套的substr()/ instr()语法比可怕的正则表达式语法更可怕。我可能是少数。无论如何,火焰离开,你知道你不能帮助自己! : - )