Ganti spasi duplikat dengan satu spasi di T-SQL

100

Saya perlu memastikan bahwa bidang tertentu tidak memiliki lebih dari satu spasi (saya tidak peduli tentang semua spasi putih, hanya spasi) di antara karakter.

Begitu

'single    spaces   only'

perlu diubah menjadi

'single spaces only'

Di bawah ini tidak akan berfungsi

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

karena akan menghasilkan

'single  spaces  only'

Saya benar-benar lebih memilih untuk tetap menggunakan T-SQL asli daripada solusi berbasis CLR.

Pikiran?

Christoph
sumber
Anda dapat melakukan ini dengan penggantian REGEX
Raj More

Jawaban:

326

Bahkan lebih rapi:

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

Keluaran:

pilih satu spasi

Neil Knight
sumber
6
Jika Anda ingin menghapus spasi di depan dan ujung string, bungkus penggantian dengan LTRIM, RTRIM dan itu akan melakukannya untuk Anda.
Neil Knight
5
Selama string Anda tidak mengandung banyak tanda <atau>. Tampaknya rapuh untuk seleraku.
JohnFx
8
Retas yang benar-benar elegan. Suara positif. Dua karakter apa pun dapat digunakan untuk bagian tengah jika <> berpotensi dalam teks masukan.
richardtallent
32
Chris, Anda dapat menggunakan karakter ASCII yang tidak dapat dicetak seperti CHAR (17) dan CHAR (18), karena ini TIDAK AKAN PERNAH ada dalam teks input Anda. Masih lebih cepat daripada mengulang jawaban yang diterima.
richardtallent
7
Saya harus benar-benar melihat ini sejenak untuk mengetahui bahwa Anda menggunakan '> <', '' Tidak ada ruang yang diganti tetapi sekarang saya mengerti ... itu sangat brilian. Saya sangat menyukai saran @richardtallent untuk menggunakan karakter ASCII yang tidak dapat dicetak yang kombinasi tambahannya menghasilkan: REPLACE (REPLACE (REPLACE (LastName, '', 'CHAR (17) CHAR (18)'), 'CHAR (18 ) CHAR (17) ',' '),' CHAR (17) CHAR (18) ',' ')
Anthony Griggs
25

Ini akan berhasil:

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

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

select @test
James Wiseman
sumber
1
Membungkus dalam fungsi dan mengubah varchar (100) menjadi nvarchar (maks)
Christoph
Perbedaan antara skrip James dan Neil adalah bahwa James menjalankan while loop yang, dalam pengalaman pribadi, menjalankannya melalui 50.000 catatan tabel cenderung sangat lambat, jadi Anda perlu membuatnya sebagai prosedur dan meneruskan catatan dan beberapa pekerjaan Anda mungkin tidak memiliki izin untuk membuat prosedur baru band. Penggunaan Neil per-ada fungsi karena menggunakan <>, jika Anda memiliki string seperti "release < now"maka Anda akan mendapatkan "release<><><<><>now", "release<<>now", "release< now", yang sama dengan pasangan simbol, jika Anda memiliki satu pun dari pasangan maka itu akan bergerak
Memor-X
1
menjalankan ini melalui catatan 50k harus secepat kilat, saya akan melihat masalah lain jika itu masalah Anda.
pengguna3486773
17

Jika Anda tahu bahwa jumlah spasi dalam satu baris tidak akan lebih dari jumlah tertentu, Anda dapat menumpuk penggantian:

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

4 pengganti harus menetapkan hingga 16 spasi berturut-turut (16, lalu 8, lalu 4, lalu 2, lalu 1)

Jika bisa jauh lebih lama, maka Anda harus melakukan sesuatu seperti fungsi in-line:

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

    RETURN @str
END

Lakukan saja

SELECT dbo.strip_spaces(myText) FROM myTable
BradC
sumber
Brad, saya memiliki kode yang hampir identik tetapi Anda mengalahkan saya sampai ke Post, jadi upvote. Beberapa panggilan REPLACE () bersifat hackish, tetapi jika jumlah ruang "ekstra" yang diharapkan dapat diprediksi dan relatif kecil, itu akan baik-baik saja dan memenuhi persyaratan OP untuk tidak memanggil kode RegEx melalui CLR.
richardtallent
6
update mytable
set myfield = replace (myfield, '  ',  ' ')
where charindex('  ', myfield) > 0 

Ganti akan berfungsi di semua spasi ganda, tidak perlu mengganti banyak. Ini adalah solusi berbasis set.

HLGEM
sumber
Bukankah ini akan menciutkan 4 ruang menjadi 2?
Christoph
Saya menyebut solusi ini dalam pertanyaan saya sebagai tidak memenuhi kebutuhan, tetapi terima kasih.
Christoph
6

Itu bisa dilakukan secara rekursif melalui fungsi:

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

lalu, misalnya:

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

kembali:

NewStr
some string with many spaces

Atau solusi berdasarkan metode yang dijelaskan oleh @ agdk26 atau @Neil Knight (tetapi lebih aman),
kedua contoh menampilkan keluaran di atas:

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

atau

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

Bagaimana itu bekerja: masukkan deskripsi gambar di sini

Perhatian:
Karakter / string yang digunakan untuk mengganti spasi tidak boleh ada di awal atau akhir string dan berdiri sendiri.

Adam Silenko
sumber
1
Saya menyukai gagasan tentang fungsi rekursif untuk ini. apakah ada hal yang harus diperhatikan?
Zach Smith
5

Ini adalah kekuatan yang kasar, tetapi akan berhasil

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
JohnFx
sumber
2

Berikut adalah fungsi sederhana yang saya buat untuk membersihkan spasi sebelum atau sesudah, dan beberapa spasi dalam sebuah string. Ini dengan anggun menangani hingga sekitar 108 ruang dalam satu regangan dan sebanyak blok yang ada di string. Anda dapat meningkatkannya dengan faktor 8 dengan menambahkan garis tambahan dengan potongan spasi yang lebih besar jika perlu. Tampaknya bekerja dengan cepat dan tidak menyebabkan masalah apa pun meskipun digunakan secara umum dalam aplikasi besar.

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
Robert Petolillo
sumber
1

Temukan ini saat menggali jawaban:

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

Jawaban lengkap (dengan penjelasan) ditarik dari: http://techtipsbysatish.blogspot.com/2010/08/sql-server-replace-multiple-spaces-with.html

Pada pandangan kedua, tampaknya hanya ada versi yang sedikit berbeda dari jawaban yang dipilih.

Orang Inggeris
sumber
1

Metode # 1

Metode pertama adalah mengganti spasi ekstra antar kata dengan kombinasi simbol yang tidak umum sebagai penanda sementara. Kemudian Anda dapat mengganti simbol penanda sementara menggunakan fungsi ganti, bukan perulangan.

Berikut adalah contoh kode yang menggantikan teks dalam variabel String.

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

Uji Waktu Eksekusi # 1: Dalam sepuluh kali operasi metode penggantian ini, waktu tunggu rata-rata pada balasan server adalah 1,7 milidetik dan total waktu eksekusi adalah 4,6 milidetik. Uji Waktu Eksekusi # 2: Waktu tunggu rata-rata pada balasan server adalah 1,7 milidetik dan total waktu eksekusi adalah 3,7 milidetik.

Metode # 2

Metode kedua tidak seanggun yang pertama, tetapi juga menyelesaikan pekerjaan. Metode ini bekerja dengan menumpuk empat (atau lebih) pernyataan ganti yang menggantikan dua spasi kosong dengan satu spasi kosong.

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

Uji Waktu Eksekusi # 1: Dalam sepuluh kali operasi metode penggantian ini, waktu tunggu rata-rata pada balasan server adalah 1,9 milidetik dan total waktu eksekusi adalah 3,8 milidetik. Uji Waktu Eksekusi # 2: Waktu tunggu rata-rata pada balasan server adalah 1,8 milidetik dan total waktu eksekusi adalah 4,8 milidetik.

Metode # 3

Metode ketiga untuk mengganti spasi ekstra antar kata adalah dengan menggunakan loop sederhana. Anda dapat melakukan pemeriksaan pada spasi ekstra di loop sementara dan kemudian menggunakan fungsi replace untuk mengurangi spasi ekstra dengan setiap iterasi loop.

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

Uji Waktu Eksekusi # 1: Dalam sepuluh kali operasi metode penggantian ini, waktu tunggu rata-rata pada balasan server adalah 1,8 milidetik dan total waktu eksekusi adalah 3,4 milidetik. Uji Waktu Eksekusi # 2: Waktu tunggu rata-rata pada balasan server adalah 1,9 milidetik dan total waktu eksekusi adalah 2,8 milidetik.


sumber
1

Ini adalah solusi melalui penggantian berganda, yang berfungsi untuk string apa pun (tidak memerlukan karakter khusus, yang bukan bagian dari string).

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'
agdk26
sumber
hal yang menyenangkan, tetapi mengubah 'abe' menjadi 'kapak'
Adam Silenko
0

Saya menggunakan solusi FOR XML PATH untuk mengganti beberapa spasi menjadi satu spasi

Idenya adalah untuk mengganti spasi dengan tag XML Kemudian membagi string XML menjadi fragmen string tanpa tag XML Akhirnya menggabungkan nilai string tersebut dengan menambahkan karakter spasi tunggal di antara dua

Berikut adalah bagaimana fungsi UDF terakhir dapat dipanggil

select dbo.ReplaceMultipleSpaces('   Sample   text  with  multiple  space     ')
Eralper
sumber
0
 DECLARE @str varchar(150)
SET @str='Hello    My   name  is Jiyaul   mustafa'
Select REPLACE(REPLACE(REPLACE(@str,' ','{}'),'}{',''),'{}',' ')
Kode
sumber
0

Saya biasanya menggunakan pendekatan ini:

declare @s varchar(50)
set @s = 'TEST         TEST'
select REPLACE(REPLACE(REPLACE(@s,' ','[o][c]'),'[c][o]',''),'[o][c]',' ')
Matthys Du Toit
sumber
0

Hanya Menambahkan Metode Lain-

Mengganti Beberapa Spasi dengan Spasi Tunggal TANPA Menggunakan REPLACE di SQL Server-

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 !
*/
Arulmouzhi
sumber
0

Temukan kode di bawah ini

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

Ini berhasil untuk saya .. Semoga ini membantu ...

Lekhnath Pandey
sumber
-1

Anda bisa mencoba ini:

select Regexp_Replace('single    spaces   only','( ){2,}', ' ') from dual;
karthika harisankar
sumber
MENYATAKAN @str varchar (150) SET @ str = 'Hello Welcome to World of .net' Pilih REPLACE (REPLACE (REPLACE (@str, '', '{}'), '} {', ''), '{ } ',' ')
Kode
-3
update mytable
set myfield = replace(myfield, '  ',  ' ')
where myfield like '%  %'

Coba ini..

Henry
sumber
Saya menyebut solusi ini dalam pertanyaan saya sebagai tidak memenuhi kebutuhan, tetapi terima kasih.
Christoph