Come rimuovere gli spazi bianchi iniziali e finali in un campo MySQL?


134

Ho una tabella con due campi (paesi e codici ISO):

Table1

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

In alcune righe il secondo campo ha spazi all'inizio e / o alla fine, il che influisce sulle query.

Table1

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

C'è un modo (in SQL) per passare attraverso la tabella e trovare / sostituire lo spazio bianco in field2?


1
Aggiungendo la mia risposta come commento per renderlo più visibile: solo per essere chiari, TRIM di default rimuove solo gli spazi (non tutti gli spazi bianchi). Ecco il documento: dev.mysql.com/doc/refman/5.0/en/…
mulya,

Risposte:


270

Stai cercando TRIM .

UPDATE FOO set FIELD2 = TRIM(FIELD2);

19
Nota: questo rimuove solo gli spazi regolari e non altri caratteri di spazi bianchi (tab, newline, ecc.)
TM.

30
sì, hai ragione @TM, quindi è meglio usarlo: AGGIORNA FOO imposta FIELD2 = TRIM (Sostituisci (Sostituisci (Sostituisci (FIELD2, '\ t', ''), '\ n', ''), '\ r' , '')); ecc.
Chris Sim,

9
Anche se la soluzione di @ ChrisSim sostituirà le nuove righe e le schede ALL'INTERNO del contenuto, ovviamente - che probabilmente non è quello che la maggior parte delle persone desidera da una funzione TRIM!
JoLoCo,

41

Una risposta generale che ho composto dalle tue risposte e da altri link e ha funzionato per me e l'ho scritta in un commento è:

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

eccetera.

Perché trim () non rimuove tutti gli spazi bianchi, quindi è meglio sostituire tutti gli spazi bianchi che desideri e piuttosto che tagliarli.

Spero di poterti aiutare con la condivisione della mia risposta :)


7
Questo rimuove tutte le schede / nuove righe. TRIM dovrebbe rimuovere gli spazi bianchi solo alle estremità della stringa.
DisgruntledGoat

1
questa è una buona idea di pensare e rimuovere i nuovi personaggi della linea, grazie, Funziona come un fascino, l'ho votato, bcoz per questo pensiero @Chris Sim
Sankar Ganesh

25

Si prega di comprendere il caso d'uso prima di utilizzare questa soluzione:

trim non funziona mentre si esegue la query di selezione

Questo funziona

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

Mentre questo non lo fa

select trim(name) from test;

9
TRIM()funziona bene per me in una SELECTdichiarazione, sono davvero curioso di sapere perché questa risposta ha così tanti voti positivi. Stai usando mysql? Quale versione?
Billynoah,

1
trim rimuove solo gli spazi iniziali
amitchhajer

11
Sì, questa risposta è sbagliata. Come sono riusciti a ottenere oltre 50 voti?
Loko,

5
Questo non è solo sbagliato, è pericoloso. Può seriamente danneggiare i dati di qualcuno.
un utente non descrittivo il

1
Ho effettuato il downgrade. Testcase: SELECT CONCAT('"', TRIM(" hello world "), '"') AS `trimmed value` FROM DUALfornisce l'output desiderato "hello world". Mentre la variante di sostituzione rimuove pericolosamente lo spazio come separatore di parole: SELECT CONCAT('"', REPLACE(" hello world ", ' ', '')) AS `replaced value` FROM DUAL fornisce l'output indesiderato"helloworld"
Piemol


11

Sembra che nessuna delle risposte correnti rimuoverà effettivamente il 100% degli spazi bianchi dall'inizio e dalla fine di una stringa.

Come menzionato in altri post, il valore predefinito TRIMrimuove solo gli spazi, non le schede, i formfeed ecc. Una combinazione di TRIMs che specifica altri caratteri di spazi bianchi può fornire un miglioramento limitato, ad es TRIM(BOTH '\r' FROM TRIM(BOTH '\n' FROM TRIM(BOTH '\f' FROM TRIM(BOTH '\t' FROM TRIM(txt))))). Ma il problema con questo approccio è che solo un singolo carattere può essere specificato per un particolare TRIMe quei caratteri vengono rimossi solo dall'inizio e dalla fine. Quindi, se la stringa che viene tagliata è qualcosa di simile \t \t \t \t(ovvero spazi e caratteri di tabulazione alternativi), TRIMsarebbero necessarie più s - e nel caso generale ciò potrebbe continuare all'infinito.

Per una soluzione leggera, dovrebbe essere possibile scrivere una semplice funzione definita dall'utente (UDF) per eseguire il lavoro eseguendo il ciclo tra i caratteri all'inizio e alla fine di una stringa. Ma non lo farò ... dato che ho già scritto un sostituto dell'espressione regolare piuttosto più pesante che può anche fare il lavoro - e può tornare utile per altri motivi, come descritto in questo post sul blog .

dimostrazione

Demo online di Rextester . In particolare, l'ultima riga mostra gli altri metodi non riusciti ma il metodo dell'espressione regolare ha esito positivo.

Funzione :

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

Uso:

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

4

Questa dichiarazione rimuoverà e aggiornerà il contenuto del campo del database

Per rimuovere gli spazi bianchi nella parte sinistra del valore del campo

UPDATE table SET field1 = LTRIM (field1);

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

Per rimuovere gli spazi bianchi nella parte destra del valore del campo

UPDATE table SETfield1 = RTRIM (field1);

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


2

Avevo bisogno di tagliare i valori in una colonna chiave primaria che aveva il nome e il cognome, quindi non volevo tagliare tutto lo spazio bianco in quanto ciò avrebbe rimosso lo spazio tra il nome e il cognome, che dovevo conservare. Ciò che ha funzionato per me è stato ...

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

o

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

o

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

Nota che la prima istanza di FIELD è tra virgolette singole, ma la seconda non è tra virgolette. Ho dovuto farlo in questo modo o mi ha dato un errore di sintassi dicendo che era una chiave primaria duplicata quando avevo entrambe le virgolette.


1

Se è necessario utilizzare il trim nella query di selezione, è anche possibile utilizzare espressioni regolari

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

restituisce righe con un campo come 'query-string'


0

puoi usare ltrim o rtrim per pulire gli spazi bianchi a destra o a sinistra o una stringa.


0

È possibile utilizzare il seguente sql, UPDATE TABLESET Column= sostituisci (Column, '', '')


-5

So che è già accettato, ma per quelli come me che cercano "rimuovi TUTTI gli spazi bianchi" (non solo all'inizio e alla fine della stringa):

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

EDIT 2019/6/20: Sì, non va bene. La funzione restituisce la parte della stringa da "quando si è verificato lo spazio dei caratteri per la prima volta". Quindi, suppongo che dicendo questo rimuova gli spazi bianchi iniziali e finali e restituisca la prima parola:

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

5
Ciò non ha rilevanza per il PO.
Mickmackusa,

4
Ehi, non stai rimuovendo tutti gli spazi bianchi , stai rimuovendo tutto dal primo spazio in poi .
Timo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.