Bagaimana menghapus spasi putih terkemuka dan tertinggal di bidang MySQL?

134

Saya memiliki tabel dengan dua bidang (negara dan kode ISO):

Table1

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

Di beberapa baris, bidang kedua memiliki spasi putih di awal dan / atau akhir, yang memengaruhi kueri.

Table1

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

Apakah ada cara (dalam SQL) untuk pergi melalui tabel dan menemukan / mengganti spasi putih di field2?

KB.
sumber
1
Menambahkan jawaban saya sebagai komentar agar lebih terlihat: Agar lebih jelas, TRIM secara default hanya menghapus spasi (tidak semua spasi putih). Inilah dokumennya
mulya

Jawaban:

270

Anda sedang mencari TRIM .

UPDATE FOO set FIELD2 = TRIM(FIELD2);
cwallenpoole
sumber
19
Catatan: ini hanya menghilangkan spasi reguler dan bukan karakter spasi putih (tab, baris baru, dll)
TM.
30
ya Anda benar @TM jadi lebih baik menggunakan: UPDATE FOO set FIELD2 = TRIM (Ganti (Ganti (Ganti (FIELD2, '\ t', ''), '\ n', ''), '\ r' , '')); dll
Chris Sim
9
Meskipun solusi @ ChrisSim akan menggantikan baris dan tab baru DALAM konten juga, tentu saja - yang mungkin bukan yang diinginkan kebanyakan orang dari fungsi TRIM!
JoLoCo
41

Jawaban umum yang saya buat dari jawaban Anda dan dari tautan lain dan itu berhasil untuk saya dan saya menulisnya dalam komentar adalah:

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

dll.

Karena trim () tidak menghapus semua spasi putih, jadi lebih baik untuk mengganti semua spasi putih yang Anda inginkan dan daripada memotongnya.

Semoga saya bisa membantu Anda membagikan jawaban saya :)

Chris Sim
sumber
7
Ini menghapus semua tab / baris baru. TRIM seharusnya hanya menghapus spasi putih di kedua ujung string.
DisgruntledGoat
1
ini ide yang bagus untuk berpikir dan menghapus karakter baris baru, terima kasih, Bekerja seperti pesona, saya telah meningkatkannya, karena pemikiran ini @Chris Sim
Sankar Ganesh
25

Harap mengerti kasus penggunaan sebelum menggunakan solusi ini:

trim tidak berfungsi saat melakukan kueri pemilihan

Ini bekerja

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

Meskipun ini tidak

select trim(name) from test;
amitchhajer
sumber
9
TRIM()berfungsi dengan baik untuk saya dalam sebuah SELECTpernyataan, saya benar-benar ingin tahu mengapa jawaban ini mendapat begitu banyak upvotes. Apakah Anda menggunakan mysql? Versi apa?
billynoah
1
trim hapus hanya spasi depan dan akhir hanya dev.mysql.com/doc/refman/5.7/en/string-functions.html
amitchhajer
11
Ya jawaban ini salah. Bagaimana ini mendapatkan 50+ upvotes?
Loko
5
Ini tidak hanya salah, itu berbahaya. Ini bisa merusak data seseorang.
pengguna yang tidak jelas
1
Saya menurunkan suara. Testcase: SELECT CONCAT('"', TRIM(" hello world "), '"') AS `trimmed value` FROM DUALmemberikan output yang diinginkan "hello world". Sementara varian ganti berbahaya menghapus ruang sebagai pemisah kata: SELECT CONCAT('"', REPLACE(" hello world ", ' ', '')) AS `replaced value` FROM DUAL memberikan hasil yang tidak diinginkan"helloworld"
Piemol
11

Tampaknya tidak ada jawaban saat ini yang benar-benar akan menghapus 100% spasi putih dari awal dan akhir string.

Seperti disebutkan dalam posting lain, defaultnya TRIMhanya menghapus spasi - bukan tab, formfeed, dll. Kombinasi dari TRIMmenentukan karakter spasi putih lainnya dapat memberikan peningkatan terbatas, mis TRIM(BOTH '\r' FROM TRIM(BOTH '\n' FROM TRIM(BOTH '\f' FROM TRIM(BOTH '\t' FROM TRIM(txt))))). Tetapi masalah dengan pendekatan ini hanya satu karakter yang dapat ditentukan untuk yang khusus TRIMdan karakter tersebut hanya dihapus dari awal dan akhir. Jadi jika string yang dipangkas adalah sesuatu seperti \t \t \t \t(yaitu spasi alternatif dan karakter tab), lebih banyak TRIMs akan diperlukan - dan dalam kasus umum ini dapat berlangsung tanpa batas.

Untuk solusi yang ringan, harus dimungkinkan untuk menulis Fungsi Didefinisikan Pengguna (UDF) sederhana untuk melakukan pekerjaan dengan mengulangi karakter pada awal dan akhir string. Tetapi saya tidak akan melakukan itu ... karena saya telah menulis sebuah pengganti ekspresi reguler yang lebih berat yang juga dapat melakukan pekerjaan - dan mungkin berguna karena alasan lain, seperti dijelaskan dalam posting blog ini .

Demo

Rextester demo online . Secara khusus, baris terakhir menunjukkan metode lain gagal tetapi metode ekspresi reguler berhasil.

Fungsi :

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

Pemakaian:

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

Pernyataan ini akan menghapus dan memperbarui konten bidang database Anda

Untuk menghapus spasi putih di sisi kiri nilai bidang

SETELAH tabel SET field1 = LTRIM (field1);

ex. SET UPDATE anggota firstName = LTRIM (firstName);

Untuk menghapus spasi putih di sisi kanan nilai bidang

Tabel UPDATE SETfield1 = RTRIM (field1);

ex. SET UPDATE anggota firstName = RTRIM (firstName);

luxknight_007
sumber
2

Saya perlu memangkas nilai-nilai dalam kolom kunci utama yang memiliki nama depan dan belakang, jadi saya tidak ingin memotong semua ruang putih karena akan menghapus ruang antara nama depan dan belakang, yang harus saya pertahankan. Apa yang berhasil untuk saya adalah ...

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

atau

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

atau

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

Perhatikan bahwa instance pertama FIELD dalam tanda kutip tunggal tetapi yang kedua tidak dalam tanda kutip sama sekali. Saya harus melakukannya dengan cara ini atau itu memberi saya kesalahan sintaks mengatakan itu adalah kunci primer duplikat ketika saya memiliki keduanya dalam tanda kutip.

MistyDawn
sumber
1

Jika Anda perlu menggunakan trim dalam kueri pemilihan, Anda juga dapat menggunakan ekspresi reguler

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

kembalikan baris dengan bidang seperti 'kueri-string'

TheSameSon
sumber
0

Anda dapat menggunakan ltrim atau rtrim untuk membersihkan spasi putih di sebelah kanan atau kiri atau string.

Tomer
sumber
0

Anda dapat menggunakan sql berikut, UPDATE TABLESET Column= ganti (Kolom, '', '')

Optimus prime
sumber
-5

Saya tahu ini sudah diterima, tetapi untuk orang-orang seperti saya yang mencari "hapus SEMUA ruang putih" (tidak hanya pada awal dan akhir dari string):

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

EDIT 2019/6/20: Ya, itu tidak baik. Fungsi mengembalikan bagian dari string sejak "ketika ruang karakter muncul untuk pertama kalinya". Jadi, saya rasa mengatakan ini menghapus spasi putih terkemuka dan tertinggal dan mengembalikan kata pertama:

select SUBSTRING_INDEX(TRIM(' 1234 243'), ' ', 1);
François Breton
sumber
5
Ini tidak memiliki relevansi dengan OP.
mickmackusa
4
Whoah, Anda tidak menghapus semua spasi putih - Anda menghapus semuanya dari ruang pertama dan seterusnya .
Timo