membername
성 및 이름이 모두 포함 된 테이블 필드 가 있습니다. 그것은 2 개에 그 분할 할 수 있는가 memberfirst
, memberlast
?
모든 레코드의 형식은 "이름 성"(따옴표없이 공백 사이)입니다.
membername
성 및 이름이 모두 포함 된 테이블 필드 가 있습니다. 그것은 2 개에 그 분할 할 수 있는가 memberfirst
, memberlast
?
모든 레코드의 형식은 "이름 성"(따옴표없이 공백 사이)입니다.
답변:
불행히도 MySQL에는 분할 문자열 기능이 없습니다. 그러나 다음 기사에서 설명하는 것과 같이이를 위해 사용자 정의 함수 를 작성할 수 있습니다 .
그 기능으로 :
DELIMITER $$
CREATE FUNCTION SPLIT_STR(
x VARCHAR(255),
delim VARCHAR(12),
pos INT
)
RETURNS VARCHAR(255) DETERMINISTIC
BEGIN
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
delim, '');
END$$
DELIMITER ;
다음과 같이 쿼리를 작성할 수 있습니다.
SELECT SPLIT_STR(membername, ' ', 1) as memberfirst,
SPLIT_STR(membername, ' ', 2) as memberlast
FROM users;
사용자 정의 함수를 사용하지 않고 쿼리를 좀 더 장황하게 만들지 않으려면 다음을 수행 할 수도 있습니다.
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(membername, ' ', 1), ' ', -1) as memberfirst,
SUBSTRING_INDEX(SUBSTRING_INDEX(membername, ' ', 2), ' ', -1) as memberlast
FROM users;
LENGTH
멀티 바이트를 안전하게 사용할 수 있습니까? "LENGTH (str) : 바이트 단위로 측정 된 문자열 str의 길이를 리턴합니다. 멀티 바이트 문자는 다중 바이트로 계산됩니다. 이는 5 개의 2 바이트 문자를 포함하는 문자열의 경우 LENGTH ()는 10을 리턴하지만 CHAR_LENGTH ()는 리턴합니다 5. "
SELECT 변형 (사용자 정의 함수를 생성하지 않음) :
SELECT IF(
LOCATE(' ', `membername`) > 0,
SUBSTRING(`membername`, 1, LOCATE(' ', `membername`) - 1),
`membername`
) AS memberfirst,
IF(
LOCATE(' ', `membername`) > 0,
SUBSTRING(`membername`, LOCATE(' ', `membername`) + 1),
NULL
) AS memberlast
FROM `user`;
이 접근법은 또한 다음을 처리합니다.
업데이트 버전은 다음과 같습니다.
UPDATE `user` SET
`memberfirst` = IF(
LOCATE(' ', `membername`) > 0,
SUBSTRING(`membername`, 1, LOCATE(' ', `membername`) - 1),
`membername`
),
`memberlast` = IF(
LOCATE(' ', `membername`) > 0,
SUBSTRING(`membername`, LOCATE(' ', `membername`) + 1),
NULL
);
기존의 답변은 너무 복잡하거나 특정 질문에 대한 엄격한 답변이 아닌 것 같습니다.
간단한 대답은 다음과 같습니다.
SELECT
SUBSTRING_INDEX(`membername`, ' ', 1) AS `memberfirst`,
SUBSTRING_INDEX(`membername`, ' ', -1) AS `memberlast`
;
이 특정 상황에서 두 단어 이상의 이름을 다룰 필요는 없다고 생각합니다. 제대로하고 싶다면 분할이 매우 어려울 수도 있고 불가능할 수도 있습니다.
올바르게 설계된 데이터베이스에서 사람 이름은 부분적으로 또는 전체적으로 저장해야합니다. 물론 이것이 항상 가능한 것은 아닙니다.
당신의 계획은의 한 부분으로이 작업을 수행하는 경우 쿼리, 제발 하지 않습니다 그렇게 (A)를 . 진심으로, 성능을 저하시키는 요인입니다. 성능에 신경 쓰지 않는 상황이있을 수 있습니다 (예 : 미래에 더 나은 성능을 제공하기 위해 필드를 분할하기위한 일회성 마이그레이션 작업). 그러나 미키 마우스 데이터베이스 이외의 다른 작업에 대해 정기적으로이 작업을 수행하는 경우 자원을 낭비하고 있습니다.
당신이 경우 지금까지 자신이 어떤 방식의 열 일부만을 처리하는 것을 발견, 당신의 DB 설계는 결함이있다. 홈 주소록이나 레시피 응용 프로그램 또는 수많은 다른 작은 데이터베이스에서는 제대로 작동하지만 "실제"시스템으로 확장 할 수는 없습니다.
이름의 구성 요소를 별도의 열에 저장하십시오. 문자 검색으로 열을 나누는 것보다 간단한 연결 (전체 이름이 필요할 때)로 열을 조인하는 것이 거의 항상 빠릅니다.
어떤 이유로 필드를 분할 할 수없는 경우 최소한 추가 열을 넣고 삽입 / 업데이트 트리거를 사용하여 필드를 채우십시오. 3NF는 아니지만 데이터의 일관성이 유지되고 쿼리 속도가 크게 향상됩니다. 또한 사례 문제를 해결하기 위해 여분의 열을 동시에 소문자로 검색하고 색인을 생성하도록 할 수도 있습니다.
또한 열과 트리거를 추가 할 수없는 경우 확장 할 수 없다는 점을 인식하고 클라이언트에게 알리십시오.
(a) 물론이 쿼리를 사용 하여 스키마 를 수정 하여 이름이 쿼리가 아닌 테이블의 별도 열에 배치 되도록하려는 경우 유효한 사용으로 간주합니다. 그러나 나는 반복하여 쿼리에서 그것을하는 것은 실제로 좋은 생각이 아닙니다.
이것을 사용하십시오
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX( `membername` , ' ', 2 ),' ',1) AS b,
SUBSTRING_INDEX(SUBSTRING_INDEX( `membername` , ' ', -1 ),' ',2) AS c FROM `users` WHERE `userid`='1'
정확히 질문에 대답하지는 않았지만 같은 문제에 직면하여 결국이 작업을 수행했습니다.
UPDATE people_exit SET last_name = SUBSTRING_INDEX(fullname,' ',-1)
UPDATE people_exit SET middle_name = TRIM(SUBSTRING_INDEX(SUBSTRING_INDEX(fullname,last_name,1),' ',-2))
UPDATE people_exit SET middle_name = '' WHERE CHAR_LENGTH(middle_name)>3
UPDATE people_exit SET first_name = SUBSTRING_INDEX(fullname,concat(middle_name,' ',last_name),1)
UPDATE people_exit SET first_name = middle_name WHERE first_name = ''
UPDATE people_exit SET middle_name = '' WHERE first_name = middle_name
MySQL에서는이 옵션이 작동합니다.
SELECT Substring(nameandsurname, 1, Locate(' ', nameandsurname) - 1) AS
firstname,
Substring(nameandsurname, Locate(' ', nameandsurname) + 1) AS lastname
FROM emp
이러한 함수를 원할 수있는 유일한 경우는 이름과 성을 별도의 필드에 저장하도록 테이블을 변경하는 UPDATE 쿼리입니다.
데이터베이스 디자인은 특정 규칙을 따라야하며 데이터베이스 정규화 는 가장 중요한 규칙 중 하나입니다.
이름과 성이 모두 한 열에있는 열이있었습니다. 성은 쉼표로 구분됩니다. 아래 코드가 작동했습니다. 오류 확인 / 수정이 없습니다. 멍청한 분할. phpMyAdmin을 사용하여 SQL 문을 실행했습니다.
UPDATE tblAuthorList SET AuthorFirst = SUBSTRING_INDEX(AuthorLast,',',-1) , AuthorLast = SUBSTRING_INDEX(AuthorLast,',',1);
이것은 여기에서 smhg를 가져오고 MySQL에서 주어진 하위 문자열의 Last index 에서 curt를 가져 와서 결합합니다. 이것은 mysql을위한 것입니다. 필요한 이름은 first_name last_name으로 이름을 나누는 것이 었습니다. 이름은 단일 단어, 이름은 단일 단어 이전의 모든 것, 여기서 이름은 null, 1 단어, 2 단어 또는 2 단어 이상. 즉 : Null; 메리; 메리 스미스; 메리 에이 스미스; 메리 수 엘렌 스미스;
따라서 name이 한 단어이거나 null이면 last_name은 null입니다. name이> 1 워드 인 경우 last_name은 마지막 단어이며 first_name은 모든 단어를 마지막 단어 앞입니다.
나는 이미 Joe Smith Jr.와 같은 것들을 다듬 었습니다. 조 스미스 Esq. 물론 수동으로도 고통 스럽지만 그렇게하기에는 충분히 작았으므로 사용할 방법을 결정하기 전에 이름 필드의 데이터를 실제로 확인해야합니다.
이것은 또한 결과를 잘라내므로 이름 앞이나 뒤에 공백이 생기지 않습니다.
나는 여기에 내가 필요한 것을 찾고있는 사람들을 위해 이것을 게시하고 있습니다. 물론 이것은 먼저 select로 테스트합니다.
일회성이므로 효율성에 관심이 없습니다.
SELECT TRIM(
IF(
LOCATE(' ', `name`) > 0,
LEFT(`name`, LENGTH(`name`) - LOCATE(' ', REVERSE(`name`))),
`name`
)
) AS first_name,
TRIM(
IF(
LOCATE(' ', `name`) > 0,
SUBSTRING_INDEX(`name`, ' ', -1) ,
NULL
)
) AS last_name
FROM `users`;
UPDATE `users` SET
`first_name` = TRIM(
IF(
LOCATE(' ', `name`) > 0,
LEFT(`name`, LENGTH(`name`) - LOCATE(' ', REVERSE(`name`))),
`name`
)
),
`last_name` = TRIM(
IF(
LOCATE(' ', `name`) > 0,
SUBSTRING_INDEX(`name`, ' ', -1) ,
NULL
)
);
방법은 데이터가 first_name 필드에 모두 도착했을 때 first_name을 first_name과 last_name으로 나누는 데 사용되었습니다. 이렇게하면 성 필드에 마지막 단어 만 입력되므로 "john phillips sousa"는 "john phillips"이름과 "sousa"성이됩니다. 또한 이미 수정 된 레코드를 덮어 쓰지 않습니다.
set last_name=trim(SUBSTRING_INDEX(first_name, ' ', -1)), first_name=trim(SUBSTRING(first_name,1,length(first_name) - length(SUBSTRING_INDEX(first_name, ' ', -1)))) where list_id='$List_ID' and length(first_name)>0 and length(trim(last_name))=0
UPDATE `salary_generation_tbl` SET
`modified_by` = IF(
LOCATE('$', `other_salary_string`) > 0,
SUBSTRING(`other_salary_string`, 1, LOCATE('$', `other_salary_string`) - 1),
`other_salary_string`
),
`other_salary` = IF(
LOCATE('$', `other_salary_string`) > 0,
SUBSTRING(`other_salary_string`, LOCATE('$', `other_salary_string`) + 1),
NULL
);