Làm cách nào để xóa khoảng trắng hàng đầu và dấu trong trường MySQL?


134

Tôi có một bảng có hai trường (quốc gia và mã ISO):

Table1

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

Trong một số hàng, trường thứ hai có khoảng trắng ở đầu và / hoặc cuối, điều này ảnh hưởng đến các truy vấn.

Table1

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

Có cách nào (trong SQL) để đi qua bảng và tìm / thay thế khoảng trắng trong trường2 không?


1
Thêm câu trả lời của tôi dưới dạng nhận xét để hiển thị rõ hơn: Để rõ ràng, TRIM theo mặc định chỉ xóa các khoảng trắng (không phải tất cả các khoảng trắng). Đây là tài liệu: dev.mysql.com/doc/refman/5.0/en/ từ
mulya

Câu trả lời:


270

Bạn đang tìm kiếm TRIM .

UPDATE FOO set FIELD2 = TRIM(FIELD2);

19
Lưu ý: điều này chỉ loại bỏ các khoảng trắng thông thường và không loại bỏ các ký tự khoảng trắng khác (tab, dòng mới, v.v.)
TM.

30
vâng, bạn đúng @TM nên sử dụng tốt hơn: CẬP NHẬT FOO đặt FIELD2 = TRIM (Thay thế (Thay thế (Thay thế (FIELD2, '\ t', ''), '\ n', ''), '\ r' , '')); v.v.
Chris Sim

9
Mặc dù giải pháp của @ ChrisSim sẽ thay thế các dòng mới và các tab cùng với nội dung, dĩ nhiên - đó có lẽ không phải là điều mà hầu hết mọi người muốn từ chức năng TRIM!
JoLoCo

41

Một câu trả lời chung mà tôi sáng tác từ câu trả lời của bạn và từ các liên kết khác và nó đã làm việc cho tôi và tôi đã viết nó trong một bình luận là:

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

Vân vân.

Bởi vì trim () không loại bỏ tất cả các khoảng trắng, vì vậy tốt hơn là thay thế tất cả các khoảng trắng bạn muốn và hơn là cắt nó.

Hy vọng tôi có thể giúp bạn chia sẻ câu trả lời của tôi :)


7
Điều này loại bỏ tất cả các tab / dòng mới. TRIM chỉ nên xóa khoảng trắng ở hai đầu của chuỗi.
DisgruntledGoat

1
Đây là một ý tưởng tốt để suy nghĩ và loại bỏ các nhân vật dòng mới, cảm ơn, Hoạt động như một cơ duyên, tôi đã nâng cao nó, bcoz cho suy nghĩ này @Chris Sim
Sankar Ganesh

25

Vui lòng hiểu trường hợp sử dụng trước khi sử dụng giải pháp này:

trim không hoạt động trong khi thực hiện chọn truy vấn

Những công việc này

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

Trong khi điều này không

select trim(name) from test;

9
TRIM()làm việc tốt với tôi trong một SELECTtuyên bố, tôi thực sự tò mò về lý do tại sao câu trả lời này lại có quá nhiều sự ủng hộ. Bạn đang sử dụng mysql? Phiên bản nào?
billynoah

1
cắt bỏ các khoảng trắng ở đầu và cuối chỉ dev.mysql.com/doc/refman/5.7/en/opes-fifts.html
amitchhajer

11
Vâng câu trả lời này là sai. Làm thế nào điều này có được hơn 50 upvote?
Loko

5
Điều này không chỉ sai, nó nguy hiểm. Nó có thể cắt xén dữ liệu của ai đó một cách nghiêm túc.
một số người dùng không mô tả

1
Tôi hạ bệ. Testcase: SELECT CONCAT('"', TRIM(" hello world "), '"') AS `trimmed value` FROM DUALcho đầu ra mong muốn "hello world". Trong khi biến thể thay thế nguy hiểm loại bỏ khoảng SELECT CONCAT('"', REPLACE(" hello world ", ' ', '')) AS `replaced value` FROM DUAL"helloworld"
trắng


11

Dường như không có câu trả lời hiện tại nào thực sự sẽ loại bỏ 100% khoảng trắng từ đầu và cuối chuỗi.

Như đã đề cập trong các bài đăng khác, mặc định TRIMchỉ xóa các khoảng trắng - không phải các tab, biểu mẫu, v.v ... Một sự kết hợp của TRIMviệc chỉ định các ký tự khoảng trắng khác có thể cung cấp một cải tiến hạn chế, ví dụ TRIM(BOTH '\r' FROM TRIM(BOTH '\n' FROM TRIM(BOTH '\f' FROM TRIM(BOTH '\t' FROM TRIM(txt))))). Nhưng vấn đề với cách tiếp cận này chỉ là một ký tự duy nhất có thể được chỉ định cho một cụ thể TRIMvà những ký tự đó chỉ bị xóa khỏi đầu và cuối. Vì vậy, nếu chuỗi được cắt bớt là một cái gì đó giống như \t \t \t \t(tức là các khoảng trắng và ký tự tab thay thế), TRIMsẽ cần nhiều s hơn - và trong trường hợp chung, điều này có thể diễn ra vô thời hạn.

Đối với một giải pháp gọn nhẹ, có thể viết Hàm xác định người dùng (UDF) đơn giản để thực hiện công việc bằng cách lặp qua các ký tự ở đầu và cuối chuỗi. Nhưng tôi sẽ không làm điều đó ... vì tôi đã viết một trình thay thế biểu thức chính quy khá nặng hơn cũng có thể thực hiện công việc - và có thể hữu ích vì những lý do khác, như được mô tả trong bài đăng trên blog này .

Bản giới thiệu

Rextester demo trực tuyến . Cụ thể, hàng cuối cùng cho thấy các phương thức khác không thành công nhưng phương thức biểu thức chính quy thành công.

Chức năng :

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

Sử dụng:

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

4

Tuyên bố này sẽ xóa và cập nhật nội dung trường của cơ sở dữ liệu của bạn

Để xóa khoảng trắng ở bên trái của giá trị trường

CẬP NHẬT bảng SET field1 = LTRIM (field1);

Ví dụ. CẬP NHẬT thành viên SET FirstName = LTRIM (FirstName);

Để xóa khoảng trắng ở bên phải của giá trị trường

Bảng CẬP NHẬT SETfield1 = RTRIM (trường1);

Ví dụ. CẬP NHẬT thành viên SET FirstName = RTRIM (FirstName);


2

Tôi cần phải cắt các giá trị trong cột khóa chính có tên và họ, vì vậy tôi không muốn cắt tất cả khoảng trắng vì điều đó sẽ xóa khoảng trắng giữa tên và họ mà tôi cần giữ. Điều làm việc cho tôi là ...

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

hoặc là

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

hoặc là

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

Lưu ý rằng phiên bản đầu tiên của FIELD nằm trong dấu ngoặc đơn nhưng lần thứ hai hoàn toàn không có dấu ngoặc kép. Tôi đã phải làm theo cách này hoặc nó đã cho tôi một lỗi cú pháp nói rằng đó là một khóa chính trùng lặp khi tôi có cả hai dấu ngoặc kép.


1

Nếu bạn cần sử dụng trim trong truy vấn chọn, bạn cũng có thể sử dụng biểu thức thông thường

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

trả về các hàng với trường như 'chuỗi truy vấn'


0

bạn có thể sử dụng ltrim hoặc rtrim để làm sạch các khoảng trắng cho bên phải hoặc bên trái hoặc một chuỗi.


0

Bạn có thể sử dụng sql sau, UPDATE TABLESET Column= thay thế (Cột, '', '')


-5

Tôi biết nó đã được chấp nhận, nhưng đối với những kẻ như tôi, người tìm kiếm "loại bỏ TẤT CẢ các khoảng trắng" (không chỉ ở đầu và kết thúc chuỗi):

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

EDIT 2019/6/20: Vâng, điều đó không tốt. Hàm trả về một phần của chuỗi vì "khi không gian ký tự xuất hiện lần đầu tiên". Vì vậy, tôi đoán rằng việc nói này sẽ loại bỏ các khoảng trắng hàng đầu và đáng sợ và trả về từ đầu tiên:

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

5
Điều này không liên quan đến OP.
mickmackusa

4
Whoah, bạn không xóa tất cả các khoảng trắng - bạn đang xóa mọi thứ từ không gian đầu tiên trở đi .
Timo
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.