[mysql] 한 필드에서 두 필드로 값 나누기

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;


답변

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

이 접근법은 또한 다음을 처리합니다.

  • 공백이없는 membername : 전체 문자열을 memberfirst에 추가하고 memberlast를 NULL로 설정합니다.
  • 공백이 여러 개인 구성원 이름 : 첫 번째 공백 앞의 모든 것을 memberfirst에 추가하고 나머지 (추가 공백 포함)를 memberlast에 추가합니다.

업데이트 버전은 다음과 같습니다.

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