[英]How to split NAME into 3 different fields FIRST_NAME, MIDDLE_NAME & LAST_NAME when there is a space
How to split NAME into 3 different fields FIRST_NAME, MIDDLE_NAME & LAST_NAME
. 如何将NAME分为3个不同的字段FIRST_NAME, MIDDLE_NAME & LAST_NAME
。
Currently the NAME filed is in the following format [FIRST_NAME || ' ' || MIDDLE_NAME|| ' ' ||LAST_NAME]
当前,NAME的格式为[FIRST_NAME || ' ' || MIDDLE_NAME|| ' ' ||LAST_NAME]
[FIRST_NAME || ' ' || MIDDLE_NAME|| ' ' ||LAST_NAME]
[FIRST_NAME || ' ' || MIDDLE_NAME|| ' ' ||LAST_NAME]
. [FIRST_NAME || ' ' || MIDDLE_NAME|| ' ' ||LAST_NAME]
。 To be more clear suppose a person name is 更清楚地说,假设一个人的名字是
FIRST_NAME: SHERRY
MIDDLE_NAME: L
LAST_NAME : CLEAVES
then the NAME field has "SHERRY L CLEAVES", I want it in 3 different fields. 那么“ NAME”字段中有“ SHERRY L CLEAVES”,我想要在3个不同的字段中输入。 Also, How do I handle if there are only two names? 另外,如果只有两个名称,该如何处理?
some of the sample data as follows: 一些样本数据如下:
('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'
)
Here's one way to do it: 这是一种实现方法:
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
Output: 输出:
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
You could do something like this. 你可以做这样的事情。 I took care of a few possibilities, like an arbitrary number of spaces between first and last name (no middle initial) or between first name and initial, or between initial and last name. 我考虑了一些可能性,例如名字和姓氏之间(无中间名字首字母)或名字和名字首字母之间,或名字和姓氏之间有任意数量的空格。 Also multi-letter initials. 也是多字母缩写。 There will still be plenty of other, unanticipated problems, like people with two first names or two last names, etc. 仍然会有很多其他未曾预料到的问题,例如姓有两个或两个的人等等。
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.
Hey don't forget regular expressions! 嘿,别忘了正则表达式! Assuming your (really too simple for names) given specs for names which assume a space for a delimiter, and the fact you are not dealing with the usual name issues, this is really just parsing a delimited string which can be done with a regex that can handle NULL list elements (the middle initial): 假设您的名称(对于名称来说确实太简单了)给定的名称规范使用了分隔符,并且您没有处理常见的名称问题,那么这实际上只是解析一个分隔字符串,可以使用正则表达式执行以下操作:可以处理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>
Yes, it's been said a million times but I'll save you the trouble: substr()/instr() is faster but I find the nested substr()/instr() syntax more ghastly than the ghastly regex syntax. 是的,已经被说了一百万遍了,但是我会为您省去麻烦:substr()/ instr()更快,但是我发现嵌套的substr()/ instr()语法比令人讨厌的regex语法更可怕。 I'm probably in the minority. 我可能是少数。 Flame away anyway, you know you can't help yourself! 不管怎样,烈焰都消失了,你知道自己无能为力! :-) :-)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.