Как удалить начальные и конечные пробелы в поле 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?

KB.
источник
1
Добавляю свой ответ в качестве комментария, чтобы сделать его более заметным: для ясности, TRIM по умолчанию удаляет только пробелы (а не все пробелы). Вот документ: dev.mysql.com/doc/refman/5.0/en/…
mulya

Ответы:

270

Вы ищете TRIM .

UPDATE FOO set FIELD2 = TRIM(FIELD2);
cwallenpoole
источник
19
Примечание: удаляются только обычные пробелы, а не другие символы пробелов (табуляция, новая строка и т. Д.)
TM.
30
да, вы правы @TM, поэтому лучше использовать: UPDATE FOO set FIELD2 = TRIM (Replace (Replace (Replace (FIELD2, '\ t', ''), '\ n', ''), '\ r' , '')); и т.д.
Крис Сим
9
Хотя решение @CrisSim, конечно же, заменит символы новой строки и табуляции ВНУТРИ контента - что, вероятно, не то, чего большинство людей хотят от функции TRIM!
JoLoCo
41

Общий ответ, который я составил из ваших ответов и из других ссылок, и он сработал для меня, и я написал его в комментарии:

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

и т.п.

Поскольку trim () не удаляет все пробелы, лучше заменить все желаемые пробелы, чем обрезать их.

Надеюсь, я смогу помочь вам поделиться своим ответом :)

Крис Сим
источник
7
Это удаляет все вкладки / новые строки. TRIM должен удалять только пробелы с обоих концов строки.
DisgruntledGoat 06
1
это хорошая идея подумать и удалить символы новой строки, спасибо, работает как шарм, я поддержал это, bcoz за такое мышление @Chris Sim
Sankar Ganesh
25

Прежде чем использовать это решение, ознакомьтесь с вариантом использования:

обрезка не работает при выполнении запроса выбора

Это работает

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

Хотя это не

select trim(name) from test;
amitchhajer
источник
9
TRIM()отлично работает для меня в SELECTзаявлении, мне действительно любопытно, почему этот ответ получил так много голосов. Вы используете MySQL? Какая версия?
billynoah
1
обрезать удалить
начальные
11
Да, это неверный ответ. Как это получило 50+ голосов?
Локо
5
Это не только неправильно, но и опасно. Это может серьезно исказить чьи-то данные.
some-non-descript-user
1
Я проголосовал против. Testcase: 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удаляются только пробелы - не вкладки, каналы и т. Д. Комбинация TRIMs, определяющая другие символы пробела, может обеспечить ограниченное улучшение, например TRIM(BOTH '\r' FROM TRIM(BOTH '\n' FROM TRIM(BOTH '\f' FROM TRIM(BOTH '\t' FROM TRIM(txt))))). Но проблема с этим подходом заключается в том, что для конкретного может быть указан только один символ, TRIMи эти символы удаляются только в начале и в конце. Поэтому, если обрезаемая строка выглядит примерно так \t \t \t \t(например, альтернативные пробелы и символы табуляции), большеTRIM потребуется s - и в общем случае это может продолжаться бесконечно.

Для облегченного решения должна быть возможность написать простую функцию, определяемую пользователем (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);

ех. UPDATE член SET firstName = LTRIM (firstName);

Чтобы удалить пробелы в правой части значения поля

ОБНОВЛЕНИЕ таблицы SETfield1 = RTRIM (field1);

ех. UPDATE член SET firstName = RTRIM (firstName);

luxknight_007
источник
2

Мне нужно было обрезать значения в столбце первичного ключа, в котором были имя и фамилия, поэтому я не хотел обрезать все пробелы, так как это удалило бы пробел между именем и фамилией, который мне нужно было сохранить. Для меня сработало ...

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

или

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

или

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

Обратите внимание, что первый экземпляр FIELD заключен в одинарные кавычки, а второй - вообще не в кавычках. Мне пришлось сделать это таким образом, иначе я получил синтаксическую ошибку, говоря, что это дублированный первичный ключ, когда у меня оба были заключены в кавычки.

MistyDawn
источник
1

Если вам нужно использовать обрезку в запросе выбора, вы также можете использовать регулярные выражения

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

возвращать строки с полем типа 'query-string'

TheSameSon
источник
0

вы можете использовать ltrim или rtrim для очистки пробелов справа или слева или строки.

Томер
источник
0

Вы можете использовать следующий sql, UPDATE TABLESET Column= replace (Column, '', '')

Оптимус Прайм
источник
-5

Я знаю, что он уже принят, но для таких людей, как я, которые ищут «удалить ВСЕ пробелы» (а не только в начале и конце строки):

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

РЕДАКТИРОВАТЬ 2019/6/20: Да, это нехорошо. Функция возвращает часть строки с момента, "когда пробел между символами возник впервые". Итак, я предполагаю, что при этом удаляются начальные и конечные пробелы и возвращается первое слово:

select SUBSTRING_INDEX(TRIM(' 1234 243'), ' ', 1);
Франсуа Бретон
источник
5
Это не имеет отношения к ОП.
mickmackusa
4
Ого, вы не удаляете все пробелы - вы удаляете все, начиная с первого пробела .
Timo