복붙노트

[SQL] SQL보기 : 전체 이름 필드에서, 첫 번째 중간 이름과 성을 구문 분석

SQL

SQL보기 : 전체 이름 필드에서, 첫 번째 중간 이름과 성을 구문 분석

어떻게 SQL과 전체 이름 필드의 첫 번째 중간, 마지막으로 이름을 구문 분석합니까?

나는 이름에 직접적인 일치하지 않은 이름을 일치하려고합니다. 나는 전체 이름 필드를 가지고, 첫번째 중간 이름과 성으로 그것을 깰 수 있도록하고 싶습니다.

데이터는 접두사 나 접미사를 포함하지 않습니다. 중간 이름은 선택 사항입니다. 데이터는 '첫 번째 중간 마지막을'포맷됩니다.

나는 나에게이 길의 90 %를 얻기 위해 몇 가지 구체적인 솔루션에 관심이 있어요. 이 언급 한 바와 같이 나는 개별적으로 특별한 경우를 처리 할 수 ​​있습니다, 그래서 이것은 복잡한 문제입니다.

해결법

  1. ==============================

    1.여기 쉽게 조작 테스트 데이터, 독립적 인 예이다.

    여기 쉽게 조작 테스트 데이터, 독립적 인 예이다.

    이상의 세 부분으로 이름이있는 경우이 예제, 다음, 모든 "추가"물건은 LAST_NAME 필드에 넣어 얻을 것이다. 예외는 "DR", "MRS"및 "MR"와 같은 "타이틀"로 식별되는 특정 문자열에 대해 이루어진다.

    중간 이름이없는 경우에, 당신은 FIRST_NAME과 LAST_NAME이 (MIDDLE_NAME이 NULL이됩니다) 얻을.

    당신은 문자열의 거대한 중첩 된 덩어리로 분쇄 할 수 있지만,이 SQL에서 할 때와 같이 가독성 하드 충분하다.

    다음과 같은 특별한 경우를 처리 Edit-- :

    - 1 NAME 필드는 NULL이다

    2 - 이름 필드 선행 / 후행 공백이 포함

    3 - 이름 필드는 이름에서> (1 개) 연속 공간이

    4 - 이름 필드는 첫 번째 이름을 포함

    5 - 가독성을 위해 별도의 열과 최종 출력의 원래 이름을 포함

    6 - 별도의 "제목"열로 프리픽스 특정 목록 핸들

    SELECT
      FIRST_NAME.ORIGINAL_INPUT_DATA
     ,FIRST_NAME.TITLE
     ,FIRST_NAME.FIRST_NAME
     ,CASE WHEN 0 = CHARINDEX(' ',FIRST_NAME.REST_OF_NAME)
           THEN NULL  --no more spaces?  assume rest is the last name
           ELSE SUBSTRING(
                           FIRST_NAME.REST_OF_NAME
                          ,1
                          ,CHARINDEX(' ',FIRST_NAME.REST_OF_NAME)-1
                         )
           END AS MIDDLE_NAME
     ,SUBSTRING(
                 FIRST_NAME.REST_OF_NAME
                ,1 + CHARINDEX(' ',FIRST_NAME.REST_OF_NAME)
                ,LEN(FIRST_NAME.REST_OF_NAME)
               ) AS LAST_NAME
    FROM
      (  
      SELECT
        TITLE.TITLE
       ,CASE WHEN 0 = CHARINDEX(' ',TITLE.REST_OF_NAME)
             THEN TITLE.REST_OF_NAME --No space? return the whole thing
             ELSE SUBSTRING(
                             TITLE.REST_OF_NAME
                            ,1
                            ,CHARINDEX(' ',TITLE.REST_OF_NAME)-1
                           )
        END AS FIRST_NAME
       ,CASE WHEN 0 = CHARINDEX(' ',TITLE.REST_OF_NAME)  
             THEN NULL  --no spaces @ all?  then 1st name is all we have
             ELSE SUBSTRING(
                             TITLE.REST_OF_NAME
                            ,CHARINDEX(' ',TITLE.REST_OF_NAME)+1
                            ,LEN(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 SUBSTRING(TEST_DATA.FULL_NAME,1,3) IN ('MR ','MS ','DR ','MRS')
               THEN LTRIM(RTRIM(SUBSTRING(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 SUBSTRING(TEST_DATA.FULL_NAME,1,3) IN ('MR ','MS ','DR ','MRS')
               THEN LTRIM(RTRIM(SUBSTRING(TEST_DATA.FULL_NAME,4,LEN(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' AS FULL_NAME
            UNION SELECT 'SUSAN B ANTHONY' AS FULL_NAME
            UNION SELECT 'ALEXANDER HAMILTON' AS FULL_NAME
            UNION SELECT 'OSAMA BIN LADEN JR' AS FULL_NAME
            UNION SELECT 'MARTIN J VAN BUREN SENIOR III' AS FULL_NAME
            UNION SELECT 'TOMMY' AS FULL_NAME
            UNION SELECT 'BILLY' AS FULL_NAME
            UNION SELECT NULL AS FULL_NAME
            UNION SELECT ' ' AS FULL_NAME
            UNION SELECT '    JOHN  JACOB     SMITH' AS FULL_NAME
            UNION SELECT ' DR  SANJAY       GUPTA' AS FULL_NAME
            UNION SELECT 'DR JOHN S HOPKINS' AS FULL_NAME
            UNION SELECT ' MRS  SUSAN ADAMS' AS FULL_NAME
            UNION SELECT ' MS AUGUSTA  ADA   KING ' AS FULL_NAME      
            ) RAW_DATA
          ) TEST_DATA
        ) TITLE
      ) FIRST_NAME
    
  2. ==============================

    2.문제를 역방향, 개별 조각을 잡고 전체 이름을 얻기 위해 그들을 결합하는 열을 추가 할 수 있습니다.

    문제를 역방향, 개별 조각을 잡고 전체 이름을 얻기 위해 그들을 결합하는 열을 추가 할 수 있습니다.

    이 가장 좋은 해답이 될 것입니다 이유는 더이 사람이 자신의 이름으로 등록되어 알아낼 방법을 보장하고, 자신의 중간 이름은 무엇 것이 없다.

    예를 들어, 당신은 어떻게이 분할 것?

    Jan Olav Olsen Heggelien
    

    fictious하면서 이것은, 노르웨이의 법적 이름이고, 할 수 있지만,이 같은 분할 될 필요가 없습니다 것입니다 :

    First name: Jan Olav
    Middle name: Olsen
    Last name: Heggelien
    

    또는,이 같은 :

    First name: Jan Olav
    Last name: Olsen Heggelien
    

    또는,이 같은 :

    First name: Jan
    Middle name: Olav
    Last name: Olsen Heggelien
    

    나는 유사한 차례 나오는 대부분의 언어에서 찾을 수 있습니다 상상할 것입니다.

    그래서 그 대신, 바로 그것을 얻을 수있는 충분한 정보를 가지고 올바른 해석을 저장하고 전체 이름을 얻기 위해 결합하지 않는 데이터를 해석하려고 노력.

  3. ==============================

    3.그것은 "이름이"포맷 방법을 아는없이 대답하기는 어렵습니다.

    그것은 "이름이"포맷 방법을 아는없이 대답하기는 어렵습니다.

    그것은 등 "성, 이름 중간 이름"또는 "이름 중간 이름 성"이 될 수

    기본적으로 당신은 SUBSTRING 기능을 사용해야합니다

    SUBSTRING ( expression , start , length )
    

    그리고 아마도 CHARINDEX 기능

    CHARINDEX (substr, expression)
    

    추출 할 각 부분의 시작과 길이를 파악합니다.

    그래서하자가 형식이 당신이 (..하지만 가까운 안된해야한다) 수 "이름 성"라고 :

    SELECT 
    SUBSTRING(fullname, 1, CHARINDEX(' ', fullname) - 1) AS FirstName, 
    SUBSTRING(fullname, CHARINDEX(' ', fullname) + 1, len(fullname)) AS LastName
    FROM YourTable
    
  4. ==============================

    4.당신은 매우, 매우 잘 행동 데이터가 없다면이 아닌 사소한 도전이다. 본래의 접근법은이 공백에 토큰 화와 세 토큰 결과는 [처음, 중간 마지막]이라고 가정하는 것입니다 및 두 개의 토큰 결과는 [먼저 마지막],하지만 당신은 다중 처리해야 할거야 단어 (예 : "밴 뷰렌") 및 다수의 중간 이름을 성씨.

    당신은 매우, 매우 잘 행동 데이터가 없다면이 아닌 사소한 도전이다. 본래의 접근법은이 공백에 토큰 화와 세 토큰 결과는 [처음, 중간 마지막]이라고 가정하는 것입니다 및 두 개의 토큰 결과는 [먼저 마지막],하지만 당신은 다중 처리해야 할거야 단어 (예 : "밴 뷰렌") 및 다수의 중간 이름을 성씨.

  5. ==============================

    5.대체 간단한 방법은 사용 parsename이다 :

    대체 간단한 방법은 사용 parsename이다 :

    select full_name,
       parsename(replace(full_name, ' ', '.'), 3) as FirstName,
       parsename(replace(full_name, ' ', '.'), 2) as MiddleName,
       parsename(replace(full_name, ' ', '.'), 1) as LastName 
    from YourTableName
    

    출처

  6. ==============================

    6.이 쿼리는 잘 작동한다.

    이 쿼리는 잘 작동한다.

    SELECT name
        ,Ltrim(SubString(name, 1, Isnull(Nullif(CHARINDEX(' ', name), 0), 1000))) AS FirstName
        ,Ltrim(SUBSTRING(name, CharIndex(' ', name), CASE 
                    WHEN (CHARINDEX(' ', name, CHARINDEX(' ', name) + 1) - CHARINDEX(' ', name)) <= 0
                        THEN 0
                    ELSE CHARINDEX(' ', name, CHARINDEX(' ', name) + 1) - CHARINDEX(' ', name)
                    END)) AS MiddleName
        ,Ltrim(SUBSTRING(name, Isnull(Nullif(CHARINDEX(' ', name, Charindex(' ', name) + 1), 0), CHARINDEX(' ', name)), CASE 
                    WHEN Charindex(' ', name) = 0
                        THEN 0
                    ELSE LEN(name)
                    END)) AS LastName
    FROM yourtableName
    
  7. ==============================

    7.당신은 전체 법적 이름이 항상 먼저, 중앙과 마지막을 포함 하시겠습니까? 나는 전체 법적 이름으로 하나의 이름을 가진 사람을 알고, 그 자신의 이름이나 성인지 솔직히 잘 모르겠습니다. :-) 나는 또한 자신의 법적 이름 하나 이상의 Fisrt 이름을 가진 사람을 알고 있지만, 중간 이름이 없습니다. 그리고 여러 중간 이름이 일부 사람들이있다.

    당신은 전체 법적 이름이 항상 먼저, 중앙과 마지막을 포함 하시겠습니까? 나는 전체 법적 이름으로 하나의 이름을 가진 사람을 알고, 그 자신의 이름이나 성인지 솔직히 잘 모르겠습니다. :-) 나는 또한 자신의 법적 이름 하나 이상의 Fisrt 이름을 가진 사람을 알고 있지만, 중간 이름이 없습니다. 그리고 여러 중간 이름이 일부 사람들이있다.

    다음 또한 전체 법적 이름에있는 이름의 순서가있다. 지금까지 내가 아는 한, 일부 아시아 문화의 마지막 이름은 실명 먼저 온다.

    좀 더 실용적인 메모에서, 당신은 공백 및 위협에 첫 번째 이름과 마지막 이름과 마지막 토큰 (또는 단 하나의 이름 만의 경우 토큰)로 첫 번째 토큰을 전체 이름을 분할 할 수있다. 하지만이 순서는 항상 동일하다고 가정한다.

  8. ==============================

    8.케이스 문자열에서이 윌 작품이다 FIRSTNAME / 가운데 이름 / 성

    케이스 문자열에서이 윌 작품이다 FIRSTNAME / 가운데 이름 / 성

    Select 
    
    DISTINCT NAMES ,
    
       SUBSTRING(NAMES , 1, CHARINDEX(' ', NAMES) - 1) as FirstName,
    
       RTRIM(LTRIM(REPLACE(REPLACE(NAMES,SUBSTRING(NAMES , 1, CHARINDEX(' ', NAMES) - 1),''),REVERSE( LEFT( REVERSE(NAMES), CHARINDEX(' ', REVERSE(NAMES))-1 ) ),'')))as MiddleName,
    
       REVERSE( LEFT( REVERSE(NAMES), CHARINDEX(' ', REVERSE(NAMES))-1 ) ) as LastName
    
    From TABLENAME
    
  9. ==============================

    9.# 1 말했듯이, 그것은 사소한 아니에요. 하이픈 성과 이름, 이니셜, 이중 이름, 역 이름 순서 및 기타 이상 현상의 다양한는 신중하게 조작 된 기능을 파괴 할 수 있습니다.

    # 1 말했듯이, 그것은 사소한 아니에요. 하이픈 성과 이름, 이니셜, 이중 이름, 역 이름 순서 및 기타 이상 현상의 다양한는 신중하게 조작 된 기능을 파괴 할 수 있습니다.

    당신은 제 3 자 라이브러리를 사용할 수 있습니다 (플러그 / 책임의 한계와 법적 고지 -이 제품에 근무) :

    http://www.melissadata.com/nameobject/nameobject.htm

  10. ==============================

    10.나는 반복적 인 프로세스로이 작업을 수행 할 것입니다.

    나는 반복적 인 프로세스로이 작업을 수행 할 것입니다.

    1) 작업 할 플랫 파일에 테이블을 덤프합니다.

    2) 분리로 공간을 사용하여 이름을 분해하는 간단한 프로그램을 작성 곳 (3) (2) 중간 이름이고 토큰 (3) 마지막 이름 다음 토큰 토큰이있는 경우, 첫 번째 이름입니다 토큰 최초. 이 토큰이있는 경우 다음 두 번째 토큰은 마지막 이름입니다. (펄, Java 또는 C / C ++ 언어는 중요하지 않습니다)

    3) 결과 안구. 이 규칙에 맞지 않는 이름을 찾습니다.

    4) 그 예를 사용하여, 그 예외를 처리하는 새로운 규칙을 만들 ...

    5) 린스와 반복

    결국 당신은 수정 모든 데이터가 프로그램을 얻을 것이다.

  11. ==============================

    11.당신은 PHP에서 인간의 이름을 따로 분석하려고하는 경우에, 나는 키스 베크의 nameparse.php 스크립트를 권장합니다.

    당신은 PHP에서 인간의 이름을 따로 분석하려고하는 경우에, 나는 키스 베크의 nameparse.php 스크립트를 권장합니다.

    경우 사이트에 복사 내려갑니다 :

    <?
    /*
    Name:   nameparse.php
    Version: 0.2a
    Date:   030507
    First:  030407
    License:    GNU General Public License v2
    Bugs:   If one of the words in the middle name is Ben (or St., for that matter),
            or any other possible last-name prefix, the name MUST be entered in
            last-name-first format. If the last-name parsing routines get ahold
            of any prefix, they tie up the rest of the name up to the suffix. i.e.:
    
            William Ben Carey   would yield 'Ben Carey' as the last name, while,
            Carey, William Ben  would yield 'Carey' as last and 'Ben' as middle.
    
            This is a problem inherent in the prefix-parsing routines algorithm,
            and probably will not be fixed. It's not my fault that there's some
            odd overlap between various languages. Just don't name your kids
            'Something Ben Something', and you should be alright.
    
    */
    
    function    norm_str($string) {
        return  trim(strtolower(
            str_replace('.','',$string)));
        }
    
    function    in_array_norm($needle,$haystack) {
        return  in_array(norm_str($needle),$haystack);
        }
    
    function    parse_name($fullname) {
        $titles         =   array('dr','miss','mr','mrs','ms','judge');
        $prefices       =   array('ben','bin','da','dal','de','del','der','de','e',
                                'la','le','san','st','ste','van','vel','von');
        $suffices       =   array('esq','esquire','jr','sr','2','ii','iii','iv');
    
        $pieces         =   explode(',',preg_replace('/\s+/',' ',trim($fullname)));
        $n_pieces       =   count($pieces);
    
        switch($n_pieces) {
            case    1:  // array(title first middles last suffix)
                $subp   =   explode(' ',trim($pieces[0]));
                $n_subp =   count($subp);
                for($i = 0; $i < $n_subp; $i++) {
                    $curr               =   trim($subp[$i]);
                    $next               =   trim($subp[$i+1]);
    
                    if($i == 0 && in_array_norm($curr,$titles)) {
                        $out['title']   =   $curr;
                        continue;
                        }
    
                    if(!$out['first']) {
                        $out['first']   =   $curr;
                        continue;
                        }
    
                    if($i == $n_subp-2 && $next && in_array_norm($next,$suffices)) {
                        if($out['last']) {
                            $out['last']    .=  " $curr";
                            }
                        else {
                            $out['last']    =   $curr;
                            }
                        $out['suffix']      =   $next;
                        break;
                        }
    
                    if($i == $n_subp-1) {
                        if($out['last']) {
                            $out['last']    .=  " $curr";
                            }
                        else {
                            $out['last']    =   $curr;
                            }
                        continue;
                        }
    
                    if(in_array_norm($curr,$prefices)) {
                        if($out['last']) {
                            $out['last']    .=  " $curr";
                            }
                        else {
                            $out['last']    =   $curr;
                            }
                        continue;
                        }
    
                    if($next == 'y' || $next == 'Y') {
                        if($out['last']) {
                            $out['last']    .=  " $curr";
                            }
                        else {
                            $out['last']    =   $curr;
                            }
                        continue;
                        }
    
                    if($out['last']) {
                        $out['last']    .=  " $curr";
                        continue;
                        }
    
                    if($out['middle']) {
                        $out['middle']      .=  " $curr";
                        }
                    else {
                        $out['middle']      =   $curr;
                        }
                    }
                break;
            case    2:
                    switch(in_array_norm($pieces[1],$suffices)) {
                        case    TRUE: // array(title first middles last,suffix)
                            $subp   =   explode(' ',trim($pieces[0]));
                            $n_subp =   count($subp);
                            for($i = 0; $i < $n_subp; $i++) {
                                $curr               =   trim($subp[$i]);
                                $next               =   trim($subp[$i+1]);
    
                                if($i == 0 && in_array_norm($curr,$titles)) {
                                    $out['title']   =   $curr;
                                    continue;
                                    }
    
                                if(!$out['first']) {
                                    $out['first']   =   $curr;
                                    continue;
                                    }
    
                                if($i == $n_subp-1) {
                                    if($out['last']) {
                                        $out['last']    .=  " $curr";
                                        }
                                    else {
                                        $out['last']    =   $curr;
                                        }
                                    continue;
                                    }
    
                                if(in_array_norm($curr,$prefices)) {
                                    if($out['last']) {
                                        $out['last']    .=  " $curr";
                                        }
                                    else {
                                        $out['last']    =   $curr;
                                        }
                                    continue;
                                    }
    
                                if($next == 'y' || $next == 'Y') {
                                    if($out['last']) {
                                        $out['last']    .=  " $curr";
                                        }
                                    else {
                                        $out['last']    =   $curr;
                                        }
                                    continue;
                                    }
    
                                if($out['last']) {
                                    $out['last']    .=  " $curr";
                                    continue;
                                    }
    
                                if($out['middle']) {
                                    $out['middle']      .=  " $curr";
                                    }
                                else {
                                    $out['middle']      =   $curr;
                                    }
                                }                       
                            $out['suffix']  =   trim($pieces[1]);
                            break;
                        case    FALSE: // array(last,title first middles suffix)
                            $subp   =   explode(' ',trim($pieces[1]));
                            $n_subp =   count($subp);
                            for($i = 0; $i < $n_subp; $i++) {
                                $curr               =   trim($subp[$i]);
                                $next               =   trim($subp[$i+1]);
    
                                if($i == 0 && in_array_norm($curr,$titles)) {
                                    $out['title']   =   $curr;
                                    continue;
                                    }
    
                                if(!$out['first']) {
                                    $out['first']   =   $curr;
                                    continue;
                                    }
    
                            if($i == $n_subp-2 && $next &&
                                in_array_norm($next,$suffices)) {
                                if($out['middle']) {
                                    $out['middle']  .=  " $curr";
                                    }
                                else {
                                    $out['middle']  =   $curr;
                                    }
                                $out['suffix']      =   $next;
                                break;
                                }
    
                            if($i == $n_subp-1 && in_array_norm($curr,$suffices)) {
                                $out['suffix']      =   $curr;
                                continue;
                                }
    
                            if($out['middle']) {
                                $out['middle']      .=  " $curr";
                                }
                            else {
                                $out['middle']      =   $curr;
                                }
                            }
                            $out['last']    =   $pieces[0];
                            break;
                        }
                unset($pieces);
                break;
            case    3:  // array(last,title first middles,suffix)
                $subp   =   explode(' ',trim($pieces[1]));
                $n_subp =   count($subp);
                for($i = 0; $i < $n_subp; $i++) {
                    $curr               =   trim($subp[$i]);
                    $next               =   trim($subp[$i+1]);
                    if($i == 0 && in_array_norm($curr,$titles)) {
                        $out['title']   =   $curr;
                        continue;
                        }
    
                    if(!$out['first']) {
                        $out['first']   =   $curr;
                        continue;
                        }
    
                    if($out['middle']) {
                        $out['middle']      .=  " $curr";
                        }
                    else {
                        $out['middle']      =   $curr;
                        }
                    }
    
                $out['last']                =   trim($pieces[0]);
                $out['suffix']              =   trim($pieces[2]);
                break;
            default:    // unparseable
                unset($pieces);
                break;
            }
    
        return $out;
        }
    
    
    ?>
    
  12. ==============================

    12.나는 / 학습 구축 / 정규 표현식을 테스트하기 위해 에스프레소를 추천합니다. 올드 무료 버전, 새로운 상용 버전

    나는 / 학습 구축 / 정규 표현식을 테스트하기 위해 에스프레소를 추천합니다. 올드 무료 버전, 새로운 상용 버전

  13. ==============================

    13.나는 한 번 임의의 문자열에서 첫번째 마지막 중간 이름을 구문 분석 할 수있는 500 문자 정규 표현식을했다. 심지어 그 빵 빵 정규식으로, 그것은 단지 때문에 입력의 전체 불일치에 약 97 %의 정확도를 얻었다. 그러나 아무것도보다.

    나는 한 번 임의의 문자열에서 첫번째 마지막 중간 이름을 구문 분석 할 수있는 500 문자 정규 표현식을했다. 심지어 그 빵 빵 정규식으로, 그것은 단지 때문에 입력의 전체 불일치에 약 97 %의 정확도를 얻었다. 그러나 아무것도보다.

  14. ==============================

    14.이미 이름에 공백 및 기타 이상 현상에 대해 제기 된주의 사항에 따라, 다음 코드 것이다 적어도 핸들 이름의 98 %. (참고 : 지저분한 SQL 나는 데이터베이스 I의 사용 정규식 옵션이 없기 때문에.)

    이미 이름에 공백 및 기타 이상 현상에 대해 제기 된주의 사항에 따라, 다음 코드 것이다 적어도 핸들 이름의 98 %. (참고 : 지저분한 SQL 나는 데이터베이스 I의 사용 정규식 옵션이 없기 때문에.)

    ** 경고 : 지저분한의 SQL은 다음과 같습니다

    create table parsname (fullname char(50), name1 char(30), name2 char(30), name3 char(30), name4 char(40));
    insert into parsname (fullname) select fullname from ImportTable;
    update parsname set name1 = substring(fullname, 1, locate(' ', fullname)),
     fullname = ltrim(substring(fullname, locate(' ', fullname), length(fullname)))
     where locate(' ', rtrim(fullname)) > 0;
    update parsname set name2 = substring(fullname, 1, locate(' ', fullname)),
     fullname = ltrim(substring(fullname, locate(' ', fullname), length(fullname)))
     where locate(' ', rtrim(fullname)) > 0;
    update parsname set name3 = substring(fullname, 1, locate(' ', fullname)),
     fullname = ltrim(substring(fullname, locate(' ', fullname), length(fullname)))
     where locate(' ', rtrim(fullname)) > 0;
    update parsname set name4 = substring(fullname, 1, locate(' ', fullname)),
     fullname = ltrim(substring(fullname, locate(' ', fullname), length(fullname)))
     where locate(' ', rtrim(fullname)) > 0;
    // fullname now contains the last word in the string.
    select fullname as FirstName, '' as MiddleName, '' as LastName from parsname where fullname is not null and name1 is null and name2 is null
    union all
    select name1 as FirstName, name2 as MiddleName, fullname as LastName from parsname where name1 is not null and name3 is null
    

    코드는 임시 테이블 (parsname)를 만들고 공백으로 전체 이름을 토큰 화하여 작동합니다. NAME3의 값 또는 NAME4로 끝나는 모든 이름은 부적합 다르게 처리해야합니다.

  15. ==============================

    15.여기에 이름, 중간 이름에 마지막 성으로 단어 사이의 모든으로 발견 된 첫 번째 단어를 넣어하는 저장 프로 시저입니다.

    여기에 이름, 중간 이름에 마지막 성으로 단어 사이의 모든으로 발견 된 첫 번째 단어를 넣어하는 저장 프로 시저입니다.

    create procedure [dbo].[import_ParseName]
    (            
        @FullName nvarchar(max),
        @FirstName nvarchar(255) output,
        @MiddleName nvarchar(255) output,
        @LastName nvarchar(255)  output
    )
    as
    begin
    
    set @FirstName = ''
    set @MiddleName = ''
    set @LastName = ''  
    set @FullName = ltrim(rtrim(@FullName))
    
    declare @ReverseFullName nvarchar(max)
    set @ReverseFullName = reverse(@FullName)
    
    declare @lengthOfFullName int
    declare @endOfFirstName int
    declare @beginningOfLastName int
    
    set @lengthOfFullName = len(@FullName)
    set @endOfFirstName = charindex(' ', @FullName)
    set @beginningOfLastName = @lengthOfFullName - charindex(' ', @ReverseFullName) + 1
    
    set @FirstName = case when @endOfFirstName <> 0 
                          then substring(@FullName, 1, @endOfFirstName - 1) 
                          else ''
                     end
    
    set @MiddleName = case when (@endOfFirstName <> 0 and @beginningOfLastName <> 0 and @beginningOfLastName > @endOfFirstName)
                           then ltrim(rtrim(substring(@FullName, @endOfFirstName , @beginningOfLastName - @endOfFirstName))) 
                           else ''
                      end
    
    set @LastName = case when @beginningOfLastName <> 0 
                         then substring(@FullName, @beginningOfLastName + 1 , @lengthOfFullName - @beginningOfLastName)
                         else ''
                    end
    
    return
    
    end 
    

    그리고 여기에 내가 그것을 호출합니다.

    DECLARE @FirstName nvarchar(255),
            @MiddleName nvarchar(255),
            @LastName nvarchar(255)
    
    EXEC    [dbo].[import_ParseName]
            @FullName = N'Scott The Other Scott Kowalczyk',
            @FirstName = @FirstName OUTPUT,
            @MiddleName = @MiddleName OUTPUT,
            @LastName = @LastName OUTPUT
    
    print   @FirstName 
    print   @MiddleName
    print   @LastName 
    
    output:
    
    Scott
    The Other Scott
    Kowalczyk
    
  16. ==============================

    16.다른 사람들이 말했듯이, 당신이 할 수없는 간단한 프로그래밍 방법에서.

    다른 사람들이 말했듯이, 당신이 할 수없는 간단한 프로그래밍 방법에서.

    이 예제를 고려하십시오

  17. ==============================

    17.나는 SQL 서버에 대한 모르겠지만, 포스트 그레스에 당신이 뭔가를 할 수 있습니다 :

    나는 SQL 서버에 대한 모르겠지만, 포스트 그레스에 당신이 뭔가를 할 수 있습니다 :

    SELECT 
      SUBSTRING(fullname, '(\\w+)') as firstname,
      SUBSTRING(fullname, '\\w+\\s(\\w+)\\s\\w+') as middle,
      COALESCE(SUBSTRING(fullname, '\\w+\\s\\w+\\s(\\w+)'), SUBSTRING(fullname, '\\w+\\s(\\w+)')) as lastname
    FROM 
    public.person
    

    정규식 표현은 아마 조금 더 간결 수 있습니다; 하지만 당신은 요점을 파악. 이것은 내가 결과에 매우 조심 것 때문에 (네덜란드에서 우리는이 많은 'Ploeg 데르 월 밴'이) 방법이 아니다 두 번 이름을 가진 사람을위한 일에 의해 수행합니다.

  18. ==============================

    18.물론 모든 우리는이 문제를 해결하는 완벽한 방법이 없다는 것을 이해하지만, 일부 솔루션은 다른 사람보다 더 당신을 얻을 수 있습니다.

    물론 모든 우리는이 문제를 해결하는 완벽한 방법이 없다는 것을 이해하지만, 일부 솔루션은 다른 사람보다 더 당신을 얻을 수 있습니다.

    특히, 그냥 일반적인 접두사 (등 씨, 박사, 부인,), infixes (폰, 드, 델, 등), 접미사 (주니어, III의 일부 목록이있는 경우 간단한 공백 스플리터을 넘어 아주 쉽게 등, 5R) 등. 당신이 일반적인 첫 번째 이름의 일부 목록이있는 경우 (다양한 언어 / 문화를 당신의 이름은 다양 경우) 그것은 당신이 중간에 단어가 성 여부의 일부가 될 가능성이 있는지 여부를 추측 할 수 있도록도 도움이됩니다.

    하여 BibTex 또한 당신에게이 방법의 일부를 얻을 몇 가지 추론을 구현; 그들은 텍스트 ::하여 BibTex :: 이름 펄 모듈에서 캡슐화하고 있습니다. 여기에 합당한 일을 빠른 코드 샘플입니다.

    use Text::BibTeX;
    use Text::BibTeX::Name;
    $name = "Dr. Mario Luis de Luigi Jr.";
    $name =~ s/^\s*([dm]rs?.?|miss)\s+//i;
    $dr=$1;
    $n=Text::BibTeX::Name->new($name);
    print join("\t", $dr, map "@{[ $n->part($_) ]}", qw(first von last jr)), "\n";
    
  19. ==============================

    19.이 일에 가장 큰 문제 I의 RAN은 "밥 R. 스미스 주니어 '같은 경우였다. 내가 사용하는 알고리즘은 http://www.blackbeltcoder.com/Articles/strings/splitting-a-name-into-first-and-last-names에 게시됩니다. 내 코드는 C #으로하지만 당신은 SQL에 있어야합니다 경우 포트를 할 수 있었다.

    이 일에 가장 큰 문제 I의 RAN은 "밥 R. 스미스 주니어 '같은 경우였다. 내가 사용하는 알고리즘은 http://www.blackbeltcoder.com/Articles/strings/splitting-a-name-into-first-and-last-names에 게시됩니다. 내 코드는 C #으로하지만 당신은 SQL에 있어야합니다 경우 포트를 할 수 있었다.

  20. ==============================

    20.@JosephStyons 및 @Digs에 의한 작업은 위대하다! 나는 SQL 서버 2016 및 최신의 새로운 기능을 만들기 위해 자신의 작품의 일부를 사용했다. 이것은 하나의 접미사뿐만 아니라 접두사를 처리합니다.

    @JosephStyons 및 @Digs에 의한 작업은 위대하다! 나는 SQL 서버 2016 및 최신의 새로운 기능을 만들기 위해 자신의 작품의 일부를 사용했다. 이것은 하나의 접미사뿐만 아니라 접두사를 처리합니다.

    CREATE FUNCTION [dbo].[NameParser]
    (
        @name nvarchar(100)
    )
    RETURNS TABLE
    AS
    RETURN (
    
    WITH prep AS (
        SELECT 
            original = @name,
            cleanName = REPLACE(REPLACE(REPLACE(REPLACE(LTRIM(RTRIM(@name)),'  ',' '),'  ',' '), '.', ''), ',', '')
    )
    SELECT
        prep.original,
        aux.prefix,
        firstName.firstName,
        middleName.middleName,
        lastName.lastName,
        aux.suffix
    FROM
        prep
        CROSS APPLY (
            SELECT 
                prefix =
                    CASE 
                        WHEN LEFT(prep.cleanName, 3) IN ('MR ', 'MS ', 'DR ', 'FR ')
                            THEN LEFT(prep.cleanName, 2)
                        WHEN LEFT(prep.cleanName, 4) IN ('MRS ', 'LRD ', 'SIR ')
                            THEN LEFT(prep.cleanName, 3)
                        WHEN LEFT(prep.cleanName, 5) IN ('LORD ', 'LADY ', 'MISS ', 'PROF ')
                            THEN LEFT(prep.cleanName, 4)
                        ELSE ''
                    END,
                suffix =
                    CASE 
                        WHEN RIGHT(prep.cleanName, 3) IN (' JR', ' SR', ' II', ' IV')
                            THEN RIGHT(prep.cleanName, 2)
                        WHEN RIGHT(prep.cleanName, 4) IN (' III', ' ESQ')
                            THEN RIGHT(prep.cleanName, 3)
                        ELSE ''
                    END
        ) aux
        CROSS APPLY (
            SELECT
                baseName = LTRIM(RTRIM(SUBSTRING(prep.cleanName, LEN(aux.prefix) + 1, LEN(prep.cleanName) - LEN(aux.prefix) - LEN(aux.suffix)))),
                numParts = (SELECT COUNT(1) FROM STRING_SPLIT(LTRIM(RTRIM(SUBSTRING(prep.cleanName, LEN(aux.prefix) + 1, LEN(prep.cleanName) - LEN(aux.prefix) - LEN(aux.suffix)))), ' '))
        ) core
        CROSS APPLY (
            SELECT
                firstName = 
                    CASE
                        WHEN core.numParts <= 1 THEN core.baseName
                        ELSE LEFT(core.baseName, CHARINDEX(' ', core.baseName, 1) - 1) 
                    END
    
        ) firstName
        CROSS APPLY (
            SELECT
                remainder = 
                    CASE
                        WHEN core.numParts <= 1 THEN ''
                        ELSE LTRIM(SUBSTRING(core.baseName, LEN(firstName.firstName) + 1, 999999))
                    END
        ) work1
        CROSS APPLY (
            SELECT
                middleName = 
                    CASE
                        WHEN core.numParts <= 2 THEN ''
                        ELSE LEFT(work1.remainder, CHARINDEX(' ', work1.remainder, 1) - 1) 
                    END
        ) middleName
        CROSS APPLY (
            SELECT
                lastName = 
                    CASE
                        WHEN core.numParts <= 1 THEN ''
                        ELSE LTRIM(SUBSTRING(work1.remainder, LEN(middleName.middleName) + 1, 999999))
                    END
        ) lastName
    )
    
    GO
    
    SELECT * FROM dbo.NameParser('Madonna')
    SELECT * FROM dbo.NameParser('Will Smith')
    SELECT * FROM dbo.NameParser('Neil Degrasse Tyson')
    SELECT * FROM dbo.NameParser('Dr. Neil Degrasse Tyson')
    SELECT * FROM dbo.NameParser('Mr. Hyde')
    SELECT * FROM dbo.NameParser('Mrs. Thurston Howell, III')
    
  21. ==============================

    21.하나의 공간 (예를 들어 첫 번째 이름 및 중간 이름의 조합) 문자열을 분리에만 아테나에서이 쿼리를 확인합니다 :

    하나의 공간 (예를 들어 첫 번째 이름 및 중간 이름의 조합) 문자열을 분리에만 아테나에서이 쿼리를 확인합니다 :

    SELECT 이름 middle_name AS, REVERSE (SUBSTR (REVERSE (이름), 1 STRPOS (REVERSE (이름), ''))) name_table FROM

    두 개 이상의 공백이 예상되면, 당신은 쉽게 위의 쿼리를 확장 할 수 있습니다.

  22. ==============================

    22.hajili의 기여 @를 기반으로 데이터가 중간 이름이 (가) 포함되어 있습니다 또는하지 않는 경우가 사건을 처리 할 수 ​​있도록, 내가 그것을 수정합니다 (parsename 기능의 창조적 사용하는 것입니다, 기간 구분은 객체의 이름을 분석하기위한 것) 때 이름이 "존과 신원 미상"입니다. 그것은 100 % 완벽 하진하지만 콤팩트 및 비즈니스 사례에 따라 트릭을 할 수 있습니다.

    hajili의 기여 @를 기반으로 데이터가 중간 이름이 (가) 포함되어 있습니다 또는하지 않는 경우가 사건을 처리 할 수 ​​있도록, 내가 그것을 수정합니다 (parsename 기능의 창조적 사용하는 것입니다, 기간 구분은 객체의 이름을 분석하기위한 것) 때 이름이 "존과 신원 미상"입니다. 그것은 100 % 완벽 하진하지만 콤팩트 및 비즈니스 사례에 따라 트릭을 할 수 있습니다.

    SELECT NAME,
    CASE WHEN parsename(replace(NAME, ' ', '.'), 4) IS NOT NULL THEN 
       parsename(replace(NAME, ' ', '.'), 4) ELSE
        CASE WHEN parsename(replace(NAME, ' ', '.'), 3) IS NOT NULL THEN 
        parsename(replace(NAME, ' ', '.'), 3) ELSE
       parsename(replace(NAME, ' ', '.'), 2) end END as FirstName
       ,
    CASE WHEN parsename(replace(NAME, ' ', '.'), 3) IS NOT NULL THEN 
       parsename(replace(NAME, ' ', '.'), 2) ELSE NULL END as MiddleName,
       parsename(replace(NAME, ' ', '.'), 1) as LastName
    from  {@YourTableName}
    
  23. ==============================

    23.Employee 테이블 열 "이름"을 가지고 있으며, 우리는 첫째, 중앙과 성으로 분할했다. 이 쿼리는 이름의 열이 '제임스 토마스'와 같은 두 단어의 값을 갖는 경우는 null로 중간 이름을 계속 처리합니다.

    Employee 테이블 열 "이름"을 가지고 있으며, 우리는 첫째, 중앙과 성으로 분할했다. 이 쿼리는 이름의 열이 '제임스 토마스'와 같은 두 단어의 값을 갖는 경우는 null로 중간 이름을 계속 처리합니다.

    UPDATE Employees
    SET [First Name] = CASE 
            WHEN (len(name) - len(Replace(name, '.', ''))) = 2
                THEN PARSENAME(Name, 3)
            WHEN (len(name) - len(Replace(name, '.', ''))) = 1
                THEN PARSENAME(Name, 2)
            ELSE PARSENAME(Name, 1)
            END
        ,[Middle Name] = CASE 
            WHEN (len(name) - len(Replace(name, '.', ''))) = 2
                THEN PARSENAME(Name, 2)
            ELSE NULL
            END
        ,[Last Name] = CASE 
            WHEN (len(name) - len(Replace(name, '.', ''))) = 2
                THEN PARSENAME(Name, 1)
            WHEN (len(name) - len(Replace(name, '.', ''))) = 1
                THEN PARSENAME(Name, 1)
            ELSE NULL
            END GO
    
    UPDATE Employee
    SET [Name] = Replace([Name], '.', ' ') GO
    
  24. from https://stackoverflow.com/questions/159567/sql-parse-the-first-middle-and-last-name-from-a-fullname-field by cc-by-sa and MIT license