Reemplazar espacios duplicados con un solo espacio en T-SQL


Necesito asegurarme de que un campo dado no tenga más de un espacio (no me preocupa todo el espacio en blanco, solo el espacio) entre caracteres.

So

'single    spaces   only'

Necesita convertirse en

'single spaces only'

Lo siguiente no funcionará

select replace('single    spaces   only','  ',' ')

Ya que resultaría en

'single  spaces  only'

Realmente preferiría seguir con T-SQL nativo en lugar de una solución basada en CLR.

Pensamientos?

Author: Peter Mortensen, 2010-03-16

12 answers

Aún más ordenado:

select string = replace(replace(replace(' select   single       spaces',' ','<>'),'><',''),'<>',' ')

Salida:

Seleccionar espacios individuales

 243
Author: Neil Knight,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-04 07:24:56

Esto funcionaría:

declare @test varchar(100)
set @test = 'this   is  a    test'

while charindex('  ',@test  ) > 0
begin
   set @test = replace(@test, '  ', ' ')
end

select @test
 18
Author: James Wiseman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-16 15:52:03

Si sabe que no habrá más de un cierto número de espacios en una fila, podría anidar el reemplazo:

replace(replace(replace(replace(myText,'  ',' '),'  ',' '),'  ',' '),'  ',' ')

4 reemplazos deben fijar hasta 16 espacios consecutivos (16, luego 8, luego 4, luego 2, luego 1)

Si pudiera ser significativamente más largo, entonces tendría que hacer algo como una función en línea:

CREATE FUNCTION strip_spaces(@str varchar(8000))
RETURNS varchar(8000) AS
BEGIN 
    WHILE CHARINDEX('  ', @str) > 0 
        SET @str = REPLACE(@str, '  ', ' ')

    RETURN @str
END

Entonces solo haz

SELECT dbo.strip_spaces(myText) FROM myTable
 11
Author: BradC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-16 15:56:38
update mytable
set myfield = replace (myfield, '  ',  ' ')
where charindex('  ', myfield) > 0 

Reemplazar funcionará en todos los espacios dobles, sin necesidad de poner varios reemplazos. Esta es la solución basada en conjuntos.

 4
Author: HLGEM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-01 14:26:42

Esto es algo de fuerza bruta, pero funcionará

CREATE FUNCTION stripDoubleSpaces(@prmSource varchar(max)) Returns varchar(max)
AS 
BEGIN
    WHILE (PATINDEX('%  %', @prmSource)>0)
     BEGIN
        SET @prmSource = replace(@prmSource  ,'  ',' ')
     END

    RETURN @prmSource
END

GO

-- Unit test -- 
PRINT dbo.stripDoubleSpaces('single    spaces   only')

single spaces only
 3
Author: JohnFx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-16 15:53:25

Se puede hacer recursivamente a través de la función:

CREATE FUNCTION dbo.RemSpaceFromStr(@str VARCHAR(MAX)) RETURNS VARCHAR(MAX) AS
BEGIN
  RETURN (CASE WHEN CHARINDEX('  ', @str) > 0 THEN
    dbo.RemSpaceFromStr(REPLACE(@str, '  ', ' ')) ELSE @str END);
END

Entonces, por ejemplo:

SELECT dbo.RemSpaceFromStr('some   string    with         many     spaces') AS NewStr

Devuelve:

NewStr
some string with many spaces

O la solución basada en el método descrito por @ agdk26 o @ Neil Knight (pero más seguro)
ambos ejemplos devuelven la salida anterior:

SELECT REPLACE(REPLACE(REPLACE('some   string    with         many     spaces'
  , '  ', ' ' + CHAR(7)), CHAR(7) + ' ', ''), ' ' + CHAR(7), ' ') AS NewStr 
--but it remove CHAR(7) (Bell) from string if exists...

O

SELECT REPLACE(REPLACE(REPLACE('some   string    with         many     spaces'
  , '  ', ' ' + CHAR(7) + CHAR(7)), CHAR(7) + CHAR(7) + ' ', ''), ' ' + CHAR(7) + CHAR(7), ' ') AS NewStr
--but it remove CHAR(7) + CHAR(7) from string

Cómo funciona: introduzca la descripción de la imagen aquí

Precaución:
Char / string usado para reemplazar espacios no debería existir al principio o al final de la cadena y estar solo.

 3
Author: Adam Silenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-04 13:05:06

Aquí hay una función simple que creé para limpiar cualquier espacio antes o después, y múltiples espacios dentro de una cadena. Maneja con gracia hasta 108 espacios en un solo tramo y tantos bloques como haya en la cuerda. Puede aumentar eso por factores de 8 agregando líneas adicionales con trozos más grandes de espacios si es necesario. Parece funcionar rápidamente y no ha causado ningún problema a pesar de su uso generalizado en una aplicación grande.

CREATE FUNCTION [dbo].[fnReplaceMultipleSpaces] (@StrVal AS VARCHAR(4000)) 
RETURNS VARCHAR(4000) 
AS 
BEGIN

    SET @StrVal = Ltrim(@StrVal)
    SET @StrVal = Rtrim(@StrVal)

    SET @StrVal = REPLACE(@StrVal, '                ', ' ')  -- 16 spaces
    SET @StrVal = REPLACE(@StrVal, '        ', ' ')  -- 8 spaces
    SET @StrVal = REPLACE(@StrVal, '    ', ' ')  -- 4 spaces
    SET @StrVal = REPLACE(@StrVal, '  ', ' ')  -- 2 spaces
    SET @StrVal = REPLACE(@StrVal, '  ', ' ')  -- 2 spaces (for odd leftovers)

RETURN @StrVal

END
 2
Author: Robert Petolillo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-10 17:56:33

Encontré esto mientras buscaba una respuesta:

SELECT REPLACE(
        REPLACE(
             REPLACE(
                LTRIM(RTRIM('1 2  3   4    5     6'))
            ,'  ',' '+CHAR(7))
        ,CHAR(7)+' ','')
    ,CHAR(7),'') AS CleanString
where charindex('  ', '1 2  3   4    5     6') > 0

La respuesta completa (con explicación) fue extraída de: http://techtipsbysatish.blogspot.com/2010/08/sql-server-replace-multiple-spaces-with.html

En el segundo vistazo, parece ser solo una versión ligeramente diferente de la respuesta seleccionada.

 1
Author: Limey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-04 22:06:10

Esta es la solución a través de reemplazo múltiple, que funciona para cualquier cadena (no necesita caracteres especiales, que no son parte de la cadena).

declare @value varchar(max)
declare @result varchar(max)
set @value = 'alpha   beta gamma  delta       xyz'

set @result = replace(replace(replace(replace(replace(replace(replace(
  @value,'a','ac'),'x','ab'),'  ',' x'),'x ',''),'x',''),'ab','x'),'ac','a')

select @result -- 'alpha beta gamma delta xyz'
 1
Author: agdk26,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-13 20:03:11

Método #1

El primer método es reemplazar espacios adicionales entre palabras con una combinación de símbolos poco común como marcador temporal. A continuación, puede reemplazar los símbolos de marcador temporales utilizando la función reemplazar en lugar de un bucle.

Aquí hay un ejemplo de código que reemplaza texto dentro de una variable de cadena.

DECLARE @testString AS VARCHAR(256) = ' Test        text   with  random*        spacing. Please normalize  this spacing!';
SELECT REPLACE(REPLACE(REPLACE(@testString, ' ', '*^'), '^*', ''), '*^', ' ');

Prueba de tiempo de ejecución # 1: En diez ejecuciones de este método de reemplazo, el tiempo de espera promedio en las respuestas del servidor fue de 1.7 milisegundos y el tiempo total de ejecución fue de 4.6 milisegundo. Prueba de tiempo de ejecución # 2: El tiempo de espera promedio en las respuestas del servidor fue de 1.7 milisegundos y el tiempo total de ejecución fue de 3.7 milisegundos.

Método # 2

El segundo método no es tan elegante como el primero, pero también hace el trabajo. Este método funciona anidando cuatro (u opcionalmente más) instrucciones replace que reemplazan dos espacios en blanco con un espacio en blanco.

DECLARE @testString AS VARCHAR(256) = ' Test        text   with  random*        spacing. Please normalize  this spacing!';
SELECT REPLACE(REPLACE(REPLACE(REPLACE(@testString,' ',' '),' ',' '),' ',' '),' ',' ')

Prueba de tiempo de ejecución # 1: En diez ejecuciones de este método de reemplazo, el tiempo de espera promedio en las respuestas del servidor fueron de 1,9 milisegundos y el tiempo total de ejecución fue de 3,8 milisegundos. Prueba de tiempo de ejecución # 2: El tiempo de espera promedio en las respuestas del servidor fue de 1.8 milisegundos y el tiempo total de ejecución fue de 4.8 milisegundos.

Método #3

El tercer método para reemplazar espacios adicionales entre palabras es usar un bucle simple. Puede verificar los espacios adicionales en un bucle while y luego usar la función reemplazar para reducir los espacios adicionales con cada iteración del bucle.

DECLARE @testString AS VARCHAR(256) = ' Test text with random* spacing. Please normalize this spacing!';
WHILE CHARINDEX(' ',@testString) > 0
SET @testString = REPLACE(@testString, ' ', ' ')
SELECT @testString

Prueba de tiempo de ejecución #1: En diez ejecuciones de este método de reemplazo, el tiempo de espera promedio en las respuestas del servidor fue de 1.8 milisegundos y el tiempo total de ejecución fue de 3.4 milisegundos. Prueba de tiempo de ejecución # 2: El tiempo de espera promedio en las respuestas del servidor fue de 1.9 milisegundos y el tiempo total de ejecución fue de 2.8 milisegundos.

 0
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-12 11:23:59
update mytable
set myfield = replace(myfield, '  ',  ' ')
where myfield like '%  %'

Prueba esto..

 -2
Author: Henry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-03 11:30:27

Puedes probar esto:

select Regexp_Replace('single    spaces   only','( ){2,}', ' ') from dual;
 -3
Author: karthika harisankar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-20 07:13:46