解析全名字段Oracle

时间:2009-06-16 19:58:14

标签: parsing oracle10g

我想知道是否有人可以帮我解析一个全名字段。 我想将它分为姓氏,名字,中间名,后缀。

以下是一些名称输入,然后是我希望如何解析它们。

                           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';

5 个答案:

答案 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名字   无论如何;