MySQL 필드에서 선행 및 후행 공백을 제거하는 방법은 무엇입니까?


134

두 개의 필드 (국가 및 ISO 코드)가있는 테이블이 있습니다.

Table1

   field1 - e.g. 'Afghanistan' (without quotes)
   field2 - e.g. 'AF'(without quotes)

일부 행의 두 번째 필드에는 시작 및 / 또는 끝에 공백이있어 쿼리에 영향을줍니다.

Table1

   field1 - e.g. 'Afghanistan' (without quotes) 
   field2 - e.g. ' AF' (without quotes but with that space in front)

SQL을 사용하여 테이블을 통과하고 field2에서 공백을 찾거나 바꾸는 방법이 있습니까?


1
답변을 주석으로 추가하여 더 잘 보이게하기 : TRIM은 기본적으로 공백 만 제거합니다 (모든 공백이 아님). 여기에 문서입니다 : dev.mysql.com/doc/refman/5.0/en/...
mulya은

답변:


270

당신은 TRIM을 찾고 있습니다.

UPDATE FOO set FIELD2 = TRIM(FIELD2);

19
참고 : 다른 공백 문자 (탭, 줄 바꿈 등)
TM

30
그렇습니다. @ TM이 맞으므로 사용하는 것이 좋습니다. UPDATE FOO set FIELD2 = TRIM (Replace (Replace (Replace (FIELD2, '\ t', '')) '' `` '')); 등
크리스 심

9
@ChrisSim의 솔루션은 물론 내용 내에서 줄 바꿈과 탭을 대체하지만 물론 대부분의 사람들이 TRIM 기능에서 원하는 것은 아닙니다!
JoLoCo

41

귀하의 답변과 다른 링크에서 구성한 일반적인 답변은 저에게 효과적이며 의견으로 작성했습니다.

 UPDATE FOO set FIELD2 = TRIM(Replace(Replace(Replace(FIELD2,'\t',''),'\n',''),'\r',''));

기타

trim ()은 모든 공백을 제거하지 않으므로 원하는 공백을 모두 바꾸고 자르는 것보다 낫습니다.

내 답변을 공유하는 데 도움이되기를 바랍니다. :)


7
모든 탭 / 줄 바꾸기가 제거됩니다. TRIM은 문자열의 양쪽 끝에서만 공백을 제거해야합니다.
DisgruntledGoat

1
이 새로운 줄 문자를 생각하고 제거하는 좋은 아이디어, 감사합니다, 매력처럼 작동합니다, 나는 그것을 생각했습니다, bcoz @Chris Sim
Sankar Ganesh

25

이 솔루션을 사용하기 전에 사용 사례를 이해하십시오.

선택 쿼리를 수행하는 동안 트림이 작동하지 않습니다

이 작동합니다

select replace(name , ' ','') from test;

이것은 아니지만

select trim(name) from test;

9
TRIM()SELECT성명서 에서 저에게 잘 작동합니다. 왜이 답변에 많은 찬사를 받았는지 궁금합니다. mysql을 사용하고 있습니까? 어떤 버전?
billynoah

1
트림 제거 최고의 만 후행 공백을 dev.mysql.com/doc/refman/5.7/en/string-functions.html
amitchhajer

11
응이 대답은 틀렸어 이것은 어떻게 50 개 이상의 투표를 얻었습니까?
Loko

5
이것은 잘못된 것일뿐만 아니라 위험합니다. 누군가의 데이터를 심각하게 왜곡시킬 수 있습니다.
설명이 아닌 사용자

1
나는 공감했다. 테스트 사례 : SELECT CONCAT('"', TRIM(" hello world "), '"') AS `trimmed value` FROM DUAL원하는 출력을 제공합니다 "hello world". 대체 변형은 단어 구분 기호로 공백을 위험하게 제거하지만 SELECT CONCAT('"', REPLACE(" hello world ", ' ', '')) AS `replaced value` FROM DUAL 원치 않는 출력 제공"helloworld"
Piemol


11

현재 답변 중 어느 것도 실제로 문자열의 시작과 끝에서 공백을 100 % 제거하지는 않는 것 같습니다.

다른 게시물에서 언급했듯이 기본값 TRIM은 탭, 용지 공급 등이 아닌 공백 만 제거합니다. TRIM다른 공백 문자를 지정 하는 조합은 예를 들어 제한적인 개선을 제공 할 수 있습니다 TRIM(BOTH '\r' FROM TRIM(BOTH '\n' FROM TRIM(BOTH '\f' FROM TRIM(BOTH '\t' FROM TRIM(txt))))). 그러나이 방법의 문제점은 특정 문자에 대해 단일 문자 만 지정할 수 있으며 TRIM해당 문자는 시작과 끝에서만 제거된다는 것입니다. 따라서 자르는 문자열이 \t \t \t \t대체 공백과 탭 문자와 같은 TRIM것이라면 더 많은 것이 필요하며 일반적으로 무한정 계속 될 수 있습니다.

경량 솔루션의 경우 문자열의 시작과 끝에서 문자를 반복하여 작업을 수행하는 간단한 UDF (사용자 정의 함수)를 작성할 수 있어야합니다. 그러나 나는 그렇게하지 않을 것입니다 ... 이 작업을 수행 할 수 있는 다소 무거운 정규식 대체기를 이미 작성 했으므로이 블로그 게시물에 설명 된 것처럼 다른 이유로 유용 할 수 있습니다 .

데모

Rextester 온라인 데모 . 특히, 마지막 행은 다른 방법은 실패하지만 정규식 방법은 성공 함을 보여줍니다.

기능 :

-- ------------------------------------------------------------------------------------
-- USAGE
-- ------------------------------------------------------------------------------------
-- SELECT reg_replace(<subject>,
--                    <pattern>,
--                    <replacement>,
--                    <greedy>,
--                    <minMatchLen>,
--                    <maxMatchLen>);
-- where:
-- <subject> is the string to look in for doing the replacements
-- <pattern> is the regular expression to match against
-- <replacement> is the replacement string
-- <greedy> is TRUE for greedy matching or FALSE for non-greedy matching
-- <minMatchLen> specifies the minimum match length
-- <maxMatchLen> specifies the maximum match length
-- (minMatchLen and maxMatchLen are used to improve efficiency but are
--  optional and can be set to 0 or NULL if not known/required)
-- Example:
-- SELECT reg_replace(txt, '^[Tt][^ ]* ', 'a', TRUE, 2, 0) FROM tbl;
DROP FUNCTION IF EXISTS reg_replace;
CREATE FUNCTION reg_replace(subject VARCHAR(21845), pattern VARCHAR(21845),
  replacement VARCHAR(21845), greedy BOOLEAN, minMatchLen INT, maxMatchLen INT)
RETURNS VARCHAR(21845) DETERMINISTIC BEGIN 
  DECLARE result, subStr, usePattern VARCHAR(21845); 
  DECLARE startPos, prevStartPos, startInc, len, lenInc INT;
  IF subject REGEXP pattern THEN
    SET result = '';
    -- Sanitize input parameter values
    SET minMatchLen = IF(minMatchLen < 1, 1, minMatchLen);
    SET maxMatchLen = IF(maxMatchLen < 1 OR maxMatchLen > CHAR_LENGTH(subject),
                         CHAR_LENGTH(subject), maxMatchLen);
    -- Set the pattern to use to match an entire string rather than part of a string
    SET usePattern = IF (LEFT(pattern, 1) = '^', pattern, CONCAT('^', pattern));
    SET usePattern = IF (RIGHT(pattern, 1) = '$', usePattern, CONCAT(usePattern, '$'));
    -- Set start position to 1 if pattern starts with ^ or doesn't end with $.
    IF LEFT(pattern, 1) = '^' OR RIGHT(pattern, 1) <> '$' THEN
      SET startPos = 1, startInc = 1;
    -- Otherwise (i.e. pattern ends with $ but doesn't start with ^): Set start position
    -- to the min or max match length from the end (depending on "greedy" flag).
    ELSEIF greedy THEN
      SET startPos = CHAR_LENGTH(subject) - maxMatchLen + 1, startInc = 1;
    ELSE
      SET startPos = CHAR_LENGTH(subject) - minMatchLen + 1, startInc = -1;
    END IF;
    WHILE startPos >= 1 AND startPos <= CHAR_LENGTH(subject)
      AND startPos + minMatchLen - 1 <= CHAR_LENGTH(subject)
      AND !(LEFT(pattern, 1) = '^' AND startPos <> 1)
      AND !(RIGHT(pattern, 1) = '$'
            AND startPos + maxMatchLen - 1 < CHAR_LENGTH(subject)) DO
      -- Set start length to maximum if matching greedily or pattern ends with $.
      -- Otherwise set starting length to the minimum match length.
      IF greedy OR RIGHT(pattern, 1) = '$' THEN
        SET len = LEAST(CHAR_LENGTH(subject) - startPos + 1, maxMatchLen), lenInc = -1;
      ELSE
        SET len = minMatchLen, lenInc = 1;
      END IF;
      SET prevStartPos = startPos;
      lenLoop: WHILE len >= 1 AND len <= maxMatchLen
                 AND startPos + len - 1 <= CHAR_LENGTH(subject)
                 AND !(RIGHT(pattern, 1) = '$' 
                       AND startPos + len - 1 <> CHAR_LENGTH(subject)) DO
        SET subStr = SUBSTRING(subject, startPos, len);
        IF subStr REGEXP usePattern THEN
          SET result = IF(startInc = 1,
                          CONCAT(result, replacement), CONCAT(replacement, result));
          SET startPos = startPos + startInc * len;
          LEAVE lenLoop;
        END IF;
        SET len = len + lenInc;
      END WHILE;
      IF (startPos = prevStartPos) THEN
        SET result = IF(startInc = 1, CONCAT(result, SUBSTRING(subject, startPos, 1)),
                        CONCAT(SUBSTRING(subject, startPos, 1), result));
        SET startPos = startPos + startInc;
      END IF;
    END WHILE;
    IF startInc = 1 AND startPos <= CHAR_LENGTH(subject) THEN
      SET result = CONCAT(result, RIGHT(subject, CHAR_LENGTH(subject) + 1 - startPos));
    ELSEIF startInc = -1 AND startPos >= 1 THEN
      SET result = CONCAT(LEFT(subject, startPos), result);
    END IF;
  ELSE
    SET result = subject;
  END IF;
  RETURN result;
END;

DROP FUNCTION IF EXISTS format_result;
CREATE FUNCTION format_result(result VARCHAR(21845))
RETURNS VARCHAR(21845) DETERMINISTIC BEGIN
  RETURN CONCAT(CONCAT('|', REPLACE(REPLACE(REPLACE(REPLACE(result, '\t', '\\t'), CHAR(12), '\\f'), '\r', '\\r'), '\n', '\\n')), '|');
END;

DROP TABLE IF EXISTS tbl;
CREATE TABLE tbl
AS
SELECT 'Afghanistan' AS txt
UNION ALL
SELECT ' AF' AS txt
UNION ALL
SELECT ' Cayman Islands  ' AS txt
UNION ALL
SELECT CONCAT(CONCAT(CONCAT('\t \t ', CHAR(12)), ' \r\n\t British Virgin Islands \t \t  ', CHAR(12)), ' \r\n') AS txt;     

SELECT format_result(txt) AS txt,
       format_result(TRIM(txt)) AS trim,
       format_result(TRIM(BOTH '\r' FROM TRIM(BOTH '\n' FROM TRIM(BOTH '\f' FROM TRIM(BOTH '\t' FROM TRIM(txt))))))
         AS `trim spaces, tabs, formfeeds and line endings`,
       format_result(reg_replace(reg_replace(txt, '^[[:space:]]+', '', TRUE, 1, 0), '[[:space:]]+$', '', TRUE, 1, 0))
         AS `reg_replace`
FROM tbl;

용법:

SELECT reg_replace(
         reg_replace(txt,
                     '^[[:space:]]+',
                     '',
                     TRUE,
                     1,
                     0),
         '[[:space:]]+$',
         '',
         TRUE,
         1,
         0) AS `trimmed txt`
FROM tbl;

4

이 문장은 데이터베이스의 필드 내용을 제거하고 업데이트합니다

필드 값의 왼쪽에서 공백을 제거하려면

업데이트 테이블 SET field1 = LTRIM (field1);

전의. 업데이트 멤버 SET firstName = LTRIM (firstName);

필드 값의 오른쪽에서 공백을 제거하려면

업데이트 테이블 SETfield1 = RTRIM (field1);

전의. 업데이트 멤버 SET firstName = RTRIM (firstName);


2

이름과 성을 가진 기본 키 열의 값을 잘라야했기 때문에 모든 공백을 자르고 싶지 않았으므로 이름과 성 사이의 공백을 제거해야했습니다. 나를 위해 일한 것은 ...

UPDATE `TABLE` SET `FIELD`= TRIM(FIELD);

또는

UPDATE 'TABLE' SET 'FIELD' = RTRIM(FIELD);

또는

UPDATE 'TABLE' SET 'FIELD' = LTRIM(FIELD);

FIELD의 첫 번째 인스턴스는 작은 따옴표 안에 있지만 두 번째 인스턴스는 따옴표가 아닙니다. 나는이 방법으로 그것을 수행해야했다.


1

선택 쿼리에서 트림을 사용해야하는 경우 정규식을 사용할 수도 있습니다.

SELECT * FROM table_name WHERE field RLIKE ' * query-string *'

'query-string'과 같은 필드가있는 행을 반환


0

ltrim 또는 rtrim을 사용하여 오른쪽 또는 왼쪽 또는 문자열의 공백을 정리할 수 있습니다.



-5

나는 이미 받아 들였지만 "문자열의 시작과 끝뿐만 아니라"모든 공백 제거 "를 찾는 나와 같은 사람들을 위해 알고 있습니다.

select SUBSTRING_INDEX('1234 243', ' ', 1);
// returns '1234'

2019/6/20 편집 : 예, 좋지 않습니다. 이 함수는 "문자 공간이 처음으로 생겼을 때"이후 문자열 부분을 반환합니다. 따라서 이것이 말하는 것은 앞뒤 공백을 제거하고 첫 단어를 반환한다고 생각합니다.

select SUBSTRING_INDEX(TRIM(' 1234 243'), ' ', 1);

5
이것은 OP와 관련이 없습니다.
mickmackusa

4
우와, 당신은 모든 공백을 제거하지 않고 - 첫 번째 공간부터 모든 것을 제거 하고 있습니다.
Timo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.