我想知道是否有人可以帮我解析一个全名字段。 我想将它分为姓氏,名字,中间名,后缀。
以下是一些名称输入,然后是我希望如何解析它们。
Parsed Stuff Begins Here-------------------------------------
name | lastname | firstname | middle initial | suffix |
----------------------------------------------------------------------------------------
PUBLIC, JOHN | PUBLIC | JOHN | NULL | NULL
PUBLIC, CHUN CH KIM | PUBLIC | CHUN CH KIM | NULL | NULL
PUBLIC, MARY L | PUBLIC | MARY | L | NULL
PUBLIC, FRED J JR | PUBLIC | FRED | J | JR
PUBLIC, SUE ELLEN J SR | PUBLIC | SUE ELLEN | J | SR
我有一个能够输入的所有后缀值的列表,即
JR, SR, I,II,III,IV,V,VI
我已经达到了一个点,我将名字和名字的其余部分分开, 但我无法弄清楚如何做其余的事情。 我正在使用oracle 10g。
这不是一个功课问题。这是我正在努力解决的一个实际问题。
以下是我目前的情况:
select id,
name,
substr(name,1, instr(name,',')-1) as lname,
substr(name,(instr(name,',')+1),length(name)) as rest_of_the_name
from my_table
where status='A';
答案 0 :(得分:2)
这是一个总会有数据打破它的问题。
如果有2个首字母怎么办?如果首字母是第一个怎么样,如J Edgar Hoover?
你提到“一个人能够进入”的价值观。您是否可以更改输入值的方式以捕获已分离的值?
答案 1 :(得分:1)
您已经部分地解决了它 - 您可以将查询用作子查询并逐位解决问题,例如:
select id, name, lname,
case
when substr(x, -2, 1) = ' '
then substr(x, length(x) - 2)
else x
end as first_name, -- e.g. "SUE ELLEN"
case
when substr(x, -2, 1) = ' '
then substr(x, -1)
else null
end as middle_initial, -- e.g. "J"
suffix -- e.g. "SR"
from (
select id, name, lname, suffix,
case when suffix is not null then
substr(rest_of_the_name, 1, length(rest_of_the_name)-length(suffix)-1)
else rest_of_the_name end
as x -- e.g. "SUE ELLEN J"
from (
select id, name, lname, rest_of_the_name,
case
when substr(rest_of_the_name,-2)
in (' I',' V')
then substr(rest_of_the_name,-1)
when substr(rest_of_the_name,-3)
in (' JR',' SR',' II',' IV',' VI')
then substr(rest_of_the_name,-2)
when substr(rest_of_the_name,-4)
in (' III')
then substr(rest_of_the_name,-3)
else null
end as suffix -- e.g. "SR"
from (
select id,
name, --e.g. "PUBLIC, SUE ELLEN J SR"
trim(substr(name,1, instr(name,',')-1)) as lname, -- e.g. "PUBLIC"
trim(substr(name,(instr(name,',')+1),length(name)))
as rest_of_the_name -- e.g. "SUE ELLEN J SR"
from my_table
where status='A'
)));
答案 2 :(得分:0)
这是一个简单的答案,基于检索名字和姓氏,以与第一个名称相同的方式检索MI,从“rest_of_the_name”中删除MI作为姓氏。
SELECT
substr('John Q. Public',1, instr('John Q. Public',' ')-1) as FirstName,
substr('John Q. Public',(instr('John Q. Public',' ')+1),length('John Q. Public')) as rest_of_the_name,
substr(substr('John Q. Public',(instr('John Q. Public',' ')+1),length('John Q. Public')),1, instr(substr('John Q. Public',(instr('John Q. Public',' ')+1),length('John Q. Public')),' ')-1) as MI,
replace(substr('John Q. Public',(instr('John Q. Public',' ')+1),length('John Q. Public')), substr(substr('John Q. Public',(instr('John Q. Public',' ')+1),length('John Q. Public')),1, instr(substr('John Q. Public',(instr('John Q. Public',' ')+1),length('John Q. Public')),' ')-1)) as LastName
FROM DUAL;
答案 3 :(得分:0)
这篇文章包含了一个非常完整的纯SQL解决方案,以SQLServer语法编写。我已经将其转换为Oracle语法。尽管它不处理后缀(Jr.,III等),但它做得很好。您应该阅读该帖子中的其他警告:
SQL: parse the first, middle and last name from a fullname field
SELECT first_name.original_input_data,
first_name.title,
first_name.first_name,
CASE
WHEN 0 = INSTR(first_name.rest_of_name, ' ') THEN
NULL --no more spaces? assume rest is the last name
ELSE
SUBSTR(first_name.rest_of_name, 1, INSTR(first_name.rest_of_name, ' ') - 1)
END AS middle_name,
SUBSTR(first_name.rest_of_name,
1 + INSTR(first_name.rest_of_name, ' '),
LENGTH(first_name.rest_of_name)) AS last_name
FROM (SELECT title.title,
CASE
WHEN 0 = INSTR(title.rest_of_name, ' ') THEN
title.rest_of_name --No space? return the whole thing
ELSE
SUBSTR(title.rest_of_name, 1, INSTR(title.rest_of_name, ' ') - 1)
END AS first_name,
CASE
WHEN 0 = INSTR(title.rest_of_name, ' ') THEN
NULL --no spaces @ all? then 1st name is all we have
ELSE
SUBSTR(title.rest_of_name, INSTR(title.rest_of_name, ' ') + 1, LENGTH(title.rest_of_name))
END AS rest_of_name,
title.original_input_data
FROM (SELECT
--if the first three characters are in this list,
--then pull it as a "title". otherwise return NULL for title.
CASE
WHEN SUBSTR(test_data.full_name, 1, 3) IN ('MR ', 'MS ', 'DR ', 'MRS') THEN
LTRIM(RTRIM(SUBSTR(test_data.full_name, 1, 3)))
ELSE
NULL
END AS title
--if you change the list, don't forget to change it here, too.
--so much for the DRY prinicple...
,
CASE
WHEN SUBSTR(test_data.full_name, 1, 3) IN ('MR ', 'MS ', 'DR ', 'MRS') THEN
LTRIM(RTRIM(SUBSTR(test_data.full_name, 4, LENGTH(test_data.full_name))))
ELSE
LTRIM(RTRIM(test_data.full_name))
END AS rest_of_name,
test_data.original_input_data
FROM (SELECT
--trim leading & trailing spaces before trying to process
--disallow extra spaces *within* the name
REPLACE(REPLACE(LTRIM(RTRIM(full_name)), ' ', ' '), ' ', ' ') AS full_name,
full_name AS original_input_data
FROM ( --if you use this, then replace the following
--block with your actual table
SELECT 'george w bush jr.' AS full_name
FROM dual
UNION
SELECT 'SUSAN B ANTHONY' AS full_name
FROM dual
UNION
SELECT 'alexander hamilton' AS full_name
FROM dual
UNION
SELECT 'osama bin laden jr' AS full_name
FROM dual
UNION
SELECT 'Martin J. VAN BUREN SENIOR III' AS full_name
FROM dual
UNION
SELECT 'Tommy' AS full_name
FROM dual
UNION
SELECT 'Billy' AS full_name
FROM dual
UNION
SELECT NULL AS full_name
FROM dual
UNION
SELECT ' ' AS full_name
FROM dual
UNION
SELECT ' JOHN JACOB SMITH' AS full_name
FROM dual
UNION
SELECT ' DR SANJAY GUPTA' AS full_name
FROM dual
UNION
SELECT 'DR JOHN S HOPKINS' AS full_name
FROM dual
UNION
SELECT ' MRS SUSAN ADAMS' AS full_name
FROM dual
UNION
SELECT ' MS AUGUSTA ADA SMITH-KING ' AS full_name
FROM dual) raw_data) test_data) title) first_name
答案 4 :(得分:-2)
选择SUBSTR(名称,INSTR(名称,'')+ 1)AS姓氏, SUBSTR(name,1,INSTR(name,'') - 1)AS名字 无论如何;