programing

T-SQL에서 중복된 공간을 단일 공간으로 바꾸기

yellowcard 2023. 5. 25. 21:39
반응형

T-SQL에서 중복된 공간을 단일 공간으로 바꾸기

지정된 필드에 문자 사이에 공백이 둘 이상 없어야 합니다(모든 공백은 상관없고 공백만 있음).

그렇게

'single    spaces   only'

로 바뀌어야 합니다.

'single spaces only'

아래는 작동하지 않습니다.

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

결과적으로

'single  spaces  only'

저는 CLR 기반 솔루션보다는 네이티브 T-SQL을 고수하고 싶습니다.

생각은?

더 깔끔하게 정리:

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

출력:

단일 공간 선택

이렇게 하면 됩니다.

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

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

select @test

연속되는 공백 수가 특정 개수를 초과하지 않을 것이라는 것을 알고 있는 경우, 다음과 같이 대체할 공간을 중첩할 수 있습니다.

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

4개의 교체로 최대 16개의 연속 공백을 수정해야 합니다(16개, 8개, 4개, 2개, 1개).

시간이 상당히 길어질 수 있는 경우 인라인 기능과 같은 작업을 수행해야 합니다.

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

    RETURN @str
END

그럼 그냥 해요

SELECT dbo.strip_spaces(myText) FROM myTable

이것은 다소 잔인한 힘이지만, 효과가 있을 것입니다.

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
update mytable
set myfield = replace (myfield, '  ',  ' ')
where charindex('  ', myfield) > 0 

Replace는 여러 개의 Replace를 추가할 필요 없이 모든 이중 공간에서 작동합니다.이것이 세트 기반 솔루션입니다.

다음 기능을 통해 재귀적으로 수행할 수 있습니다.

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

예를 들어 다음과 같습니다.

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

반환:

NewStr
some string with many spaces

@Knight 더안전함)에 기술된 @agdk26 @Neil Knight @Neil Knight (Neil Knight )
모두위의 합니다. " 예 모 두 위 반 니 합 다 환 을 력 출 두 의▁both 다니 합▁output ▁above: ▁return환

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

또는

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

작동 방식:

주의:
공백을 대체하는 데 사용되는 문자/문자열은 문자열의 시작 또는 끝에 존재하지 않아야 하며 독립형이어야 합니다.

다음은 문자열 전후의 공백과 문자열 내의 여러 공백을 정리하기 위해 만든 간단한 함수입니다.그것은 한 번의 스트레치에서 최대 108개의 공간과 문자열에 있는 만큼의 블록을 우아하게 처리합니다.필요한 경우 공백 청크가 더 큰 선을 추가하여 8배까지 늘릴 수 있습니다.대규모 애플리케이션에서 일반적으로 사용되고 있음에도 불구하고 성능이 빠르게 향상되고 문제가 발생하지 않았습니다.

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

방법 #1

첫 번째 방법은 단어 사이의 추가 공백을 임시 마커로 일반적이지 않은 기호 조합으로 바꾸는 것입니다.그런 다음 루프 대신 교체 기능을 사용하여 임시 마커 기호를 바꿀 수 있습니다.

다음은 문자열 변수 내의 텍스트를 대체하는 코드 예제입니다.

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

실행 시간 테스트 #1: 이 대체 방법을 10번 실행했을 때 서버 응답의 평균 대기 시간은 1.7밀리초, 총 실행 시간은 4.6밀리초였습니다.실행 시간 테스트 #2:서버 응답의 평균 대기 시간은 1.7밀리초이고 총 실행 시간은 3.7밀리초입니다.

방법 #2

두 번째 방법은 첫 번째 방법만큼 우아하지는 않지만, 일을 수행합니다.이 방법은 두 개의 빈 공간을 하나의 빈 공간으로 바꾸는 네 개의 문(또는 선택적으로 더 많은 문)을 중첩하여 사용할 수 있습니다.

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

실행 시간 테스트 #1: 이 대체 방법을 10번 실행했을 때 서버 응답의 평균 대기 시간은 1.9밀리초, 총 실행 시간은 3.8밀리초였습니다.실행 시간 테스트 #2:서버 응답의 평균 대기 시간은 1.8밀리초이고 총 실행 시간은 4.8밀리초입니다.

방법 #3

단어 사이의 여분의 공간을 대체하는 세 번째 방법은 간단한 루프를 사용하는 것입니다.잠시 동안 루프의 추가 공간을 확인한 다음 교체 기능을 사용하여 루프를 반복할 때마다 추가 공간을 줄일 수 있습니다.

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

실행 시간 테스트 #1: 이 대체 방법을 10번 실행했을 때 서버 응답의 평균 대기 시간은 1.8밀리초, 총 실행 시간은 3.4밀리초였습니다.실행 시간 테스트 #2:서버 응답의 평균 대기 시간은 1.9밀리초이고 총 실행 시간은 2.8밀리초입니다.

이는 문자열에 대해 작동하는 다중 바꾸기를 통한 솔루션입니다(문자열의 일부가 아닌 특수 문자가 필요하지 않음).

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'

사용해 볼 수 있습니다.

select Regexp_Replace('single    spaces   only','( ){2,}', ' ') from dual;

다른 방법을 추가하는 것뿐

SQL Server에서 REPLACE를 사용하지 않고 여러 공간을 단일 공간으로 교체

DECLARE @TestTable AS TABLE(input VARCHAR(MAX));

INSERT INTO @TestTable VALUES
('HAPPY         NEWYEAR     2020'),
('WELCOME       ALL     !');

SELECT
    CAST('<r><![CDATA[' + input + ']]></r>' AS XML).value('(/r/text())[1] cast as xs:token?','VARCHAR(MAX)')
    AS Expected_Result
FROM @TestTable;

--OUTPUT
/*
Expected_Result
HAPPY NEWYEAR 2020
WELCOME ALL !
*/

답을 찾는 동안 발견된 정보:

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

전체 답변(설명 포함)은 http://techtipsbysatish.blogspot.com/2010/08/sql-server-replace-multiple-spaces-with.html 에서 가져왔습니다.

다시 보면, 선택한 답변의 약간 다른 버전인 것 같습니다.

아래코찾오시십으를을 찾아주세요.

select trim(string_agg(value,' ')) from STRING_SPLIT('  single    spaces   only  ',' ')
where value<>' '

제게 효과가 있었습니다.이게 도움이 되길...

버전 130하면 "" Server " (호환성 레벨 130)"을 사용할 .string_split그리고.string_agg.

string_proxy는 세 번째 인수와 함께 제공될 때 순서 열을 반환할 수 있습니다.(https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql?view=sql-server-ver16#enable_ordinal) .그래서 우리는 질서를 보존할 수 있습니다.string_split.

공통 테이블 식 사용:

with cte(value) as (select value from string_split('  a b   c d     e     ', ' ', 1) where value <> '' order by ordinal offset 0 rows)
select string_agg(value, ' ') from cte

a b c d e 의 결과.a b c d e

여러 공간을 단일 공간으로 바꾸기 위해 FOR XML PATH 솔루션을 사용합니다.

이 아이디어는 공간을 XML 태그로 바꾼 다음 XML 문자열을 XML 태그 없이 문자열 조각으로 분할합니다. 마지막으로 두 개 사이에 단일 공백 문자를 추가하여 해당 문자열 값을 연결합니다.

최종 UDF 함수를 호출하는 방법은 다음과 같습니다.

select dbo.ReplaceMultipleSpaces('   Sample   text  with  multiple  space     ')

언급URL : https://stackoverflow.com/questions/2455750/replace-duplicate-spaces-with-a-single-space-in-t-sql

반응형