[SQL] SQL보기 : 전체 이름 필드에서, 첫 번째 중간 이름과 성을 구문 분석
SQLSQL보기 : 전체 이름 필드에서, 첫 번째 중간 이름과 성을 구문 분석
어떻게 SQL과 전체 이름 필드의 첫 번째 중간, 마지막으로 이름을 구문 분석합니까?
나는 이름에 직접적인 일치하지 않은 이름을 일치하려고합니다. 나는 전체 이름 필드를 가지고, 첫번째 중간 이름과 성으로 그것을 깰 수 있도록하고 싶습니다.
데이터는 접두사 나 접미사를 포함하지 않습니다. 중간 이름은 선택 사항입니다. 데이터는 '첫 번째 중간 마지막을'포맷됩니다.
나는 나에게이 길의 90 %를 얻기 위해 몇 가지 구체적인 솔루션에 관심이 있어요. 이 언급 한 바와 같이 나는 개별적으로 특별한 경우를 처리 할 수 있습니다, 그래서 이것은 복잡한 문제입니다.
해결법
-
==============================
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.문제를 역방향, 개별 조각을 잡고 전체 이름을 얻기 위해 그들을 결합하는 열을 추가 할 수 있습니다.
문제를 역방향, 개별 조각을 잡고 전체 이름을 얻기 위해 그들을 결합하는 열을 추가 할 수 있습니다.
이 가장 좋은 해답이 될 것입니다 이유는 더이 사람이 자신의 이름으로 등록되어 알아낼 방법을 보장하고, 자신의 중간 이름은 무엇 것이 없다.
예를 들어, 당신은 어떻게이 분할 것?
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.그것은 "이름이"포맷 방법을 아는없이 대답하기는 어렵습니다.
그것은 "이름이"포맷 방법을 아는없이 대답하기는 어렵습니다.
그것은 등 "성, 이름 중간 이름"또는 "이름 중간 이름 성"이 될 수
기본적으로 당신은 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.당신은 매우, 매우 잘 행동 데이터가 없다면이 아닌 사소한 도전이다. 본래의 접근법은이 공백에 토큰 화와 세 토큰 결과는 [처음, 중간 마지막]이라고 가정하는 것입니다 및 두 개의 토큰 결과는 [먼저 마지막],하지만 당신은 다중 처리해야 할거야 단어 (예 : "밴 뷰렌") 및 다수의 중간 이름을 성씨.
당신은 매우, 매우 잘 행동 데이터가 없다면이 아닌 사소한 도전이다. 본래의 접근법은이 공백에 토큰 화와 세 토큰 결과는 [처음, 중간 마지막]이라고 가정하는 것입니다 및 두 개의 토큰 결과는 [먼저 마지막],하지만 당신은 다중 처리해야 할거야 단어 (예 : "밴 뷰렌") 및 다수의 중간 이름을 성씨.
-
==============================
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.이 쿼리는 잘 작동한다.
이 쿼리는 잘 작동한다.
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.당신은 전체 법적 이름이 항상 먼저, 중앙과 마지막을 포함 하시겠습니까? 나는 전체 법적 이름으로 하나의 이름을 가진 사람을 알고, 그 자신의 이름이나 성인지 솔직히 잘 모르겠습니다. :-) 나는 또한 자신의 법적 이름 하나 이상의 Fisrt 이름을 가진 사람을 알고 있지만, 중간 이름이 없습니다. 그리고 여러 중간 이름이 일부 사람들이있다.
당신은 전체 법적 이름이 항상 먼저, 중앙과 마지막을 포함 하시겠습니까? 나는 전체 법적 이름으로 하나의 이름을 가진 사람을 알고, 그 자신의 이름이나 성인지 솔직히 잘 모르겠습니다. :-) 나는 또한 자신의 법적 이름 하나 이상의 Fisrt 이름을 가진 사람을 알고 있지만, 중간 이름이 없습니다. 그리고 여러 중간 이름이 일부 사람들이있다.
다음 또한 전체 법적 이름에있는 이름의 순서가있다. 지금까지 내가 아는 한, 일부 아시아 문화의 마지막 이름은 실명 먼저 온다.
좀 더 실용적인 메모에서, 당신은 공백 및 위협에 첫 번째 이름과 마지막 이름과 마지막 토큰 (또는 단 하나의 이름 만의 경우 토큰)로 첫 번째 토큰을 전체 이름을 분할 할 수있다. 하지만이 순서는 항상 동일하다고 가정한다.
-
==============================
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.# 1 말했듯이, 그것은 사소한 아니에요. 하이픈 성과 이름, 이니셜, 이중 이름, 역 이름 순서 및 기타 이상 현상의 다양한는 신중하게 조작 된 기능을 파괴 할 수 있습니다.
# 1 말했듯이, 그것은 사소한 아니에요. 하이픈 성과 이름, 이니셜, 이중 이름, 역 이름 순서 및 기타 이상 현상의 다양한는 신중하게 조작 된 기능을 파괴 할 수 있습니다.
당신은 제 3 자 라이브러리를 사용할 수 있습니다 (플러그 / 책임의 한계와 법적 고지 -이 제품에 근무) :
http://www.melissadata.com/nameobject/nameobject.htm
-
==============================
10.나는 반복적 인 프로세스로이 작업을 수행 할 것입니다.
나는 반복적 인 프로세스로이 작업을 수행 할 것입니다.
1) 작업 할 플랫 파일에 테이블을 덤프합니다.
2) 분리로 공간을 사용하여 이름을 분해하는 간단한 프로그램을 작성 곳 (3) (2) 중간 이름이고 토큰 (3) 마지막 이름 다음 토큰 토큰이있는 경우, 첫 번째 이름입니다 토큰 최초. 이 토큰이있는 경우 다음 두 번째 토큰은 마지막 이름입니다. (펄, Java 또는 C / C ++ 언어는 중요하지 않습니다)
3) 결과 안구. 이 규칙에 맞지 않는 이름을 찾습니다.
4) 그 예를 사용하여, 그 예외를 처리하는 새로운 규칙을 만들 ...
5) 린스와 반복
결국 당신은 수정 모든 데이터가 프로그램을 얻을 것이다.
-
==============================
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.나는 / 학습 구축 / 정규 표현식을 테스트하기 위해 에스프레소를 추천합니다. 올드 무료 버전, 새로운 상용 버전
나는 / 학습 구축 / 정규 표현식을 테스트하기 위해 에스프레소를 추천합니다. 올드 무료 버전, 새로운 상용 버전
-
==============================
13.나는 한 번 임의의 문자열에서 첫번째 마지막 중간 이름을 구문 분석 할 수있는 500 문자 정규 표현식을했다. 심지어 그 빵 빵 정규식으로, 그것은 단지 때문에 입력의 전체 불일치에 약 97 %의 정확도를 얻었다. 그러나 아무것도보다.
나는 한 번 임의의 문자열에서 첫번째 마지막 중간 이름을 구문 분석 할 수있는 500 문자 정규 표현식을했다. 심지어 그 빵 빵 정규식으로, 그것은 단지 때문에 입력의 전체 불일치에 약 97 %의 정확도를 얻었다. 그러나 아무것도보다.
-
==============================
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.여기에 이름, 중간 이름에 마지막 성으로 단어 사이의 모든으로 발견 된 첫 번째 단어를 넣어하는 저장 프로 시저입니다.
여기에 이름, 중간 이름에 마지막 성으로 단어 사이의 모든으로 발견 된 첫 번째 단어를 넣어하는 저장 프로 시저입니다.
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.다른 사람들이 말했듯이, 당신이 할 수없는 간단한 프로그래밍 방법에서.
다른 사람들이 말했듯이, 당신이 할 수없는 간단한 프로그래밍 방법에서.
이 예제를 고려하십시오
-
==============================
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.물론 모든 우리는이 문제를 해결하는 완벽한 방법이 없다는 것을 이해하지만, 일부 솔루션은 다른 사람보다 더 당신을 얻을 수 있습니다.
물론 모든 우리는이 문제를 해결하는 완벽한 방법이 없다는 것을 이해하지만, 일부 솔루션은 다른 사람보다 더 당신을 얻을 수 있습니다.
특히, 그냥 일반적인 접두사 (등 씨, 박사, 부인,), 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.이 일에 가장 큰 문제 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.@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.하나의 공간 (예를 들어 첫 번째 이름 및 중간 이름의 조합) 문자열을 분리에만 아테나에서이 쿼리를 확인합니다 :
하나의 공간 (예를 들어 첫 번째 이름 및 중간 이름의 조합) 문자열을 분리에만 아테나에서이 쿼리를 확인합니다 :
SELECT 이름 middle_name AS, REVERSE (SUBSTR (REVERSE (이름), 1 STRPOS (REVERSE (이름), ''))) name_table FROM
두 개 이상의 공백이 예상되면, 당신은 쉽게 위의 쿼리를 확장 할 수 있습니다.
-
==============================
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.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
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
'SQL' 카테고리의 다른 글
[SQL] 집계 함수없이 GROUP BY (0) | 2020.04.18 |
---|---|
[SQL] EXECUTE 후 트랜잭션 개수가 일치하지 않는 BEGIN 및 COMMIT 문을 수를 나타냅니다. 이전 카운트 = 1, 현재 카운트 = 0 (0) | 2020.04.18 |
[SQL] 어떻게 저장 프로 시저에서 여러 행을 반환? (오라클 PL / SQL) (0) | 2020.04.17 |
[SQL] JPQL IN 절 : 자바 배열 (또는 목록, 설정 ...)? (0) | 2020.04.17 |
[SQL] 영구적으로 설정 PostgreSQL을 스키마 경로 (0) | 2020.04.17 |