0

我想知道是否有人可以帮助我解析全名字段。我想把它分成姓氏、名字、中间名首字母、后缀。

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

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

5 回答 5

2

这是一个总会有数据破坏它的问题。

如果有2个首字母怎么办?如果首字母是第一个,如 J Edgar Hoover 怎么办?

您提到“可以输入的值”。您可以更改输入值的方式以捕获已经分离的值吗?

于 2009-06-16T20:25:47.847 回答
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'
)));
于 2009-06-17T02:16:20.633 回答
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;
于 2010-01-08T19:46:04.977 回答
0

这篇文章包含一个非常完整的纯 SQL 解决方案,用 SQLServer 语法编写。我已将其转换为 Oracle 语法。它做得很好,尽管它不处理后缀(Jr.、III 等)。您应该阅读帖子中的其他警告:

SQL:从全名字段中解析名字、中间名和姓氏

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
于 2020-01-17T19:12:46.767 回答
-2

选择 SUBSTR(name, INSTR(name, ' ')+1) AS lastname, SUBSTR(name, 1, INSTR(name, ' ')-1) AS firstname 任意;

于 2013-12-03T04:39:16.083 回答