T-SQLで重複するスペースを1つのスペースに置き換える


100

特定のフィールドの文字間に複数のスペースがないことを確認する必要があります(すべての空白は気にせず、スペースのみを気にします)。

そう

'single    spaces   only'

に変える必要がある

'single spaces only'

以下は動作しません

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

結果として

'single  spaces  only'

CLRベースのソリューションではなく、ネイティブのT-SQLを使用するほうがいいと思います。

考え?


これは、REGEXの置換で実行できます
Raj More

回答:


325

整頓:

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

出力:

シングルスペースを選択


6
文字列の前後のスペースを削除したい場合は、置換をLTRIM、RTRIMでラップすると、自動的に行われます。
Neil Knight

5
文字列に多数の<または>記号が含まれていない限り。私の好みで壊れやすいようです。
JohnFx 2010年

8
本当にエレガントなハック。賛成。<>が入力テキストに含まれている可能性がある場合は、中間部分に任意の2文字を使用できます。
richardtallent 2010年

32
Chris、入力テキストには決して含まれないので、CHAR(17)やCHAR(18)などの印刷不可能なASCII文字を使用できます。受け入れられた回答のループよりもさらに高速です。
richardtallent 2010年

7
私はあなたが '> <'を使っていることを理解するために少しの間これを実際に見なければなりませんでした」@richardtallentの提案のように、追加した組み合わせによって生成される印刷不可能なASCII文字を使用するという提案を非常によく行いました。REPLACE(REPLACE(REPLACE(LastName、 ''、 'C​​HAR(17)CHAR(18)')、 'CHAR(18 )CHAR(17) '、' ')、' CHAR(17)CHAR(18) '、' ')
Anthony Griggs

25

これはうまくいくでしょう:

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

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

select @test

1
関数をラップしてvarchar(100)をnvarchar(max)に変更
Christoph

JamesとNeilのスクリプトの違いは、Jamesがwhileループを実行するということです。個人的な経験では、テーブルの50,000レコードを実行するのは非常に遅い傾向があるため、プロシージャとして作成し、レコードといくつかを渡す必要があります。バンドの新しいプロシージャを作成する権限がないジョブ。ニールの用途ごとの既存のそれは、<使用しているため>あなたのような文字列を持っている場合は、機能を"release < now"あなたは得るでしょう"release<><><<><>now""release<<>now""release< now"あなたはペアの単一のものを持っている場合は、そのシンボルの任意のペアと同じ、移動するために起こっています
Memor-X

1
これを5万件のレコードで実行すると、速くなるはずです。それがあなたの問題である場合は、他の問題を調べます。
user3486773 2017

17

行のスペースが特定の数を超えないことがわかっている場合は、置換をネストすることができます。

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

ブラッド、私はほとんど同じコードを持っていたが、あなたは私をポストに打ち負かしたので、賛成票を投じた。複数のREPLACE()呼び出しはやりがいがありますが、予想される「余分な」スペースの数が予測可能で比較的少ない場合、問題なく動作し、CLRを介してRegExコードを呼び出さないというOPの要件を満たします。
richardtallent 2010年

6
update mytable
set myfield = replace (myfield, '  ',  ' ')
where charindex('  ', myfield) > 0 

置換はすべての二重スペースで機能し、複数の置換を配置する必要はありません。これは、セットベースのソリューションです。


これは4つのスペースを2つに縮めないでしょうか。
Christoph

私の質問では、この解決策を必要性を満たしていないと呼びましたが、感謝します。
クリストフ

6

これは、関数を介して再帰的に実行できます。

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

または、@ agdk26または@Neil Knight(しかしより安全)によって記述された方法に基づくソリューションは、
上記の出力を返します。

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

使い方: ここに画像の説明を入力してください

注意:
スペースの置換に使用される文字/文字列は、文字列の最初または最後に存在してはならず、スタンドアロンである必要があります。


1
私はこのための再帰関数のアイデアが好きです。知っておくべきことはありますか?
Zach Smith

5

これは多少ブルートフォースですが、機能します

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

2

これは、文字列内の前後のスペース、および文字列内の複数のスペースを削除するために作成した簡単な関数です。1回のストレッチで最大約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

答えを探しているときにこれを見つけました:

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

見直すと、選択した回答のバージョンが少し異なるようです。


1

方法#1

最初の方法は、一時的なマーカーとして、単語間の余分なスペースを珍しい記号の組み合わせに置き換えることです。次に、ループではなく置換関数を使用して一時マーカーシンボルを置換できます。

以下は、String変数内のテキストを置き換えるコード例です。

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

2番目の方法は、1番目の方法ほど洗練されていませんが、作業も完了します。この方法は、2つの空白スペースを1つの空白スペースに置き換える4つ(またはオプションでそれ以上)のreplaceステートメントをネストすることで機能します。

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

単語間の余分なスペースを置き換える3番目の方法は、単純なループを使用することです。whileループで余分なスペースをチェックし、replace関数を使用して、ループの反復ごとに余分なスペースを減らすことができます。

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ミリ秒でした。


1

これは、複数の置換によるソリューションであり、任意の文字列に対して機能します(文字列の一部ではない特殊文字は必要ありません)。

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'

いいことですが、 'abe'を 'axe'に変更します
Adam Silenko

0

FOR XML PATHソリューションを使用して、複数のスペースを1つのスペース置き換えます

アイデアは、スペースをXMLタグで置き換えることです。次に、XML文字列をXMLタグなしの文字列フラグメントに分割します。最後に、2つの文字列の間にスペース文字を1つ追加して、これらの文字列値を連結します。

最終的なUDF関数を呼び出す方法は次のとおりです

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


0

私は通常、このアプローチを使用します。

declare @s varchar(50)
set @s = 'TEST         TEST'
select REPLACE(REPLACE(REPLACE(@s,' ','[o][c]'),'[c][o]',''),'[o][c]',' ')

0

別のメソッドを追加するだけ

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 !
*/

0

コードを見つけてください

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

これは私のために働いた..これが役に立てば幸い...


-1

あなたはこれを試すことができます:

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

DECLARE @str varchar(150)SET @ str = 'Hello Welcome to World of .net'を選択REPLACE(REPLACE(REPLACE(@str、 ''、 '{}')、 '} {'、 '')、 '{ } '、' ')
ジヤウルムスタファ

-3
update mytable
set myfield = replace(myfield, '  ',  ' ')
where myfield like '%  %'

これを試して..


私の質問では、この解決策を必要性を満たしていないと呼びましたが、感謝します。
クリストフ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.