【SQL Server】空白を削除する方法|TRIM・LTRIM・RTRIM・REPLACEで前後・全角スペースを除去

【SQL Server】空白を削除する方法|TRIM・LTRIM・RTRIM・REPLACEで前後・全角スペースを除去 SQL

SQL Serverで文字列の空白を削除したいときは、前後だけを削除するのか、文字列中の空白もすべて削除するのかで使う関数が変わります。前後の半角スペースならTRIM、古い環境ではLTRIMRTRIM、文字列中の空白や全角スペース、タブ、改行を消すならREPLACEを使います。

この記事では、SQL Serverで空白を削除するSQLを、実務でそのまま使いやすい形で整理します。登録データのクリーニング、検索条件、UPDATEでの一括補正、インデックスへの影響まで扱います。

先に結論
前後の空白だけならTRIM(列名)、左だけならLTRIM、右だけならRTRIMです。文字列の途中にある空白も消すならREPLACE(列名, ' ', '')を使います。全角スペースは半角スペースとは別文字なので、REPLACE(列名, NCHAR(12288), '')のように明示して削除します。
スポンサーリンク

コピペ用の基本パターン

まずは、よく使う空白削除SQLだけを先に示します。列名を置き換えれば、SELECTで確認してからUPDATEにも応用できます。

copy-and-paste-space-cleanup.sql
-- 前後の半角スペースを削除
SELECT TRIM(CustomerName) AS cleaned_name
FROM dbo.Customers;

-- SQL Server 2016以前など、TRIMが使えない環境
SELECT LTRIM(RTRIM(CustomerName)) AS cleaned_name
FROM dbo.Customers;

-- 半角スペースをすべて削除
SELECT REPLACE(CustomerName, N' ', N'') AS cleaned_name
FROM dbo.Customers;

-- 全角スペースをすべて削除
SELECT REPLACE(CustomerName, NCHAR(12288), N'') AS cleaned_name
FROM dbo.Customers;
SQL Serverの環境 前後の空白削除 補足
SQL Server 2016以前 LTRIM(RTRIM(col)) TRIMは使わない前提
SQL Server 2017以降 TRIM(col) 前後の半角スペース削除に使いやすい
SQL Server 2022以降 + 互換性レベル160 TRIM(LEADING ...) 片側指定や削除文字指定の幅が広がる

バージョン差分が分からない場合は、まずLTRIM(RTRIM(col))で書くと古い環境でも通しやすいです。新しい環境で読みやすさを優先するならTRIM(col)を使います。

空白削除の早見表

最初に、よくある目的別の書き方をまとめます。空白といっても、半角スペース、全角スペース、タブ、改行は別の文字です。

やりたいこと 使うSQL 注意点
前後の半角スペースを削除 TRIM(col) SQL Server 2017以降で使いやすい
左側だけ削除 LTRIM(col) 先頭の半角スペースを削除
右側だけ削除 RTRIM(col) 末尾の半角スペースを削除
古い環境で前後削除 LTRIM(RTRIM(col)) TRIMが使えない環境向け
文字列中の半角スペースも削除 REPLACE(col, ' ', '') 前後だけでなくすべて消える
全角スペースを削除 REPLACE(col, NCHAR(12288), '') 半角スペースとは別に処理する
タブを削除 REPLACE(col, CHAR(9), '') タブ文字だけを消す
改行を削除 REPLACE(REPLACE(col, CHAR(13), ''), CHAR(10), '') CR/LFを別々に消す

前後の空白はTRIMで削除する

SQL Serverで前後の半角スペースを削除するなら、まずTRIMを使います。Microsoft Learnでは、TRIMは既定で文字列の先頭と末尾からchar(32)のスペースを削除すると説明されています。

trim-basic.sql
SELECT
    TRIM('  SQL Server  ') AS trimmed_value;

結果はSQL Serverになります。ただし、これは文字列の途中にあるスペースまでは削除しません。

trim-keeps-inner-space.sql
SELECT
    TRIM('  SQL Server  ') AS result;
-- result: 'SQL Server'
-- SQL と Server の間のスペースは残る

古い環境ではLTRIMとRTRIMを組み合わせる

TRIMが使えない古いSQL Serverでは、LTRIMRTRIMを組み合わせます。前後の空白を消すなら、昔からよく使われる書き方は次の形です。

ltrim-rtrim-basic.sql
SELECT
    LTRIM(RTRIM('  SQL Server  ')) AS trimmed_value;

LTRIMは左側、RTRIMは右側の空白を削除します。SQL Server 2017以降ならTRIMのほうが読みやすいですが、古い互換性を意識する現場ではLTRIM(RTRIM(...))もまだ見かけます。

左だけ・右だけ削除する

先頭だけ、末尾だけを削除したい場合は、LTRIMまたはRTRIMを使います。

left-right-trim.sql
SELECT
    LTRIM('  ABC  ') AS left_trimmed,
    RTRIM('  ABC  ') AS right_trimmed;

SQL Server 2022以降で、かつデータベース互換性レベルが160なら、TRIM(LEADING ...)TRIM(TRAILING ...)も使えます。ただし互換性レベルの条件があるため、幅広い環境で動かしたいSQLではLTRIMRTRIMも選択肢になります。

trim-leading-trailing-sqlserver2022.sql
-- SQL Server 2022以降 + 互換性レベル160で利用
SELECT
    TRIM(LEADING ' ' FROM '  ABC  ') AS left_trimmed,
    TRIM(TRAILING ' ' FROM '  ABC  ') AS right_trimmed;

文字列中の空白も消すならREPLACEを使う

前後だけでなく、文字列の途中にある半角スペースもすべて削除したい場合はREPLACEを使います。REPLACEは指定した文字列を別の文字列へ置換する関数です。

replace-halfwidth-space.sql
SELECT
    REPLACE('A B C D', ' ', '') AS no_space;
-- result: 'ABCD'

電話番号、郵便番号、コード値など、途中の空白も含めて消したい場合に使います。名前や住所のように、単語間の空白に意味があるデータでは消しすぎに注意してください。

全角スペースを削除する

日本語データでは、半角スペースではなく全角スペースが混ざることがあります。全角スペースは半角スペースとは別の文字なので、TRIM(col)REPLACE(col, ' ', '')だけでは消えないことがあります。

replace-fullwidth-space.sql
SELECT
    REPLACE(N'山田 太郎', NCHAR(12288), N'') AS no_fullwidth_space;
-- result: N'山田太郎'

NCHAR(12288)は全角スペースを表します。半角スペースと全角スペースの両方を消したいなら、REPLACEを重ねます。

remove-halfwidth-and-fullwidth-space.sql
SELECT
    REPLACE(
        REPLACE(N' 山田 太郎 ', N' ', N''),
        NCHAR(12288),
        N''
    ) AS normalized_name;
-- result: N'山田太郎'

タブや改行を削除する

CSV取込や外部連携のデータでは、タブや改行が混ざっていることがあります。タブはCHAR(9)、改行はCHAR(13)CHAR(10)を対象にします。

remove-tab-and-newline.sql
SELECT
    REPLACE(
        REPLACE(
            REPLACE(CommentText, CHAR(9), ''),
            CHAR(13),
            ''
        ),
        CHAR(10),
        ''
    ) AS cleaned_text
FROM dbo.ImportRows;

改行を完全に削除するのではなく、半角スペースへ置き換えたい場合は、置換後の文字を''ではなく' 'にします。文章データでは削除より置換のほうが読みやすくなることがあります。

複数の空白を1つにまとめたい場合

SQL Serverには、複数の空白を一度で1つにまとめる標準的なTRIM構文はありません。単純な半角スペースの連続なら、REPLACEを繰り返して寄せる方法があります。

collapse-repeated-spaces.sql
DECLARE @value nvarchar(100) = N'山田    太郎';

WHILE CHARINDEX(N'  ', @value) > 0
BEGIN
    SET @value = REPLACE(@value, N'  ', N' ');
END;

SELECT @value AS normalized_value;

大量データに対して毎回この処理を行うと重くなりやすいため、アプリ側の入力時チェックや、取り込み時の正規化処理も検討します。

UPDATEで空白を一括削除する

既存テーブルのデータをクリーニングする場合は、いきなり全件UPDATEせず、まず対象件数と変更後の値を確認します。

preview-cleanup-target.sql
SELECT TOP (100)
    CustomerID,
    CustomerName AS before_value,
    TRIM(CustomerName) AS after_value
FROM dbo.Customers
WHERE CustomerName <> TRIM(CustomerName);

問題なければ、トランザクションを使って更新します。

update-trim-customer-name.sql
BEGIN TRAN;

UPDATE dbo.Customers
SET CustomerName = TRIM(CustomerName)
WHERE CustomerName <> TRIM(CustomerName);

-- 件数と内容を確認してから確定
-- COMMIT;
-- ROLLBACK;

本番で大量更新する場合は、更新件数、ロック時間、ログ増加に注意します。一括更新で影響が大きい場合は、TOPを使って小分けに処理します。

batch-update-trim.sql
WHILE 1 = 1
BEGIN
    UPDATE TOP (1000) dbo.Customers
    SET CustomerName = TRIM(CustomerName)
    WHERE CustomerName <> TRIM(CustomerName);

    IF @@ROWCOUNT = 0 BREAK;
END;

SQL ServerでTOPやOFFSET FETCHを使う方法

WHERE句でTRIMを使うときの注意

検索条件でTRIM(CustomerName) = N'山田太郎'のように書くと、列に関数をかけるため、通常のインデックスが効きにくくなることがあります。少量データなら問題にならなくても、大きなテーブルでは注意が必要です。

trim-in-where-can-be-slow.sql
-- インデックスが効きにくくなることがある
SELECT CustomerID, CustomerName
FROM dbo.Customers
WHERE TRIM(CustomerName) = N'山田太郎';

よく検索する項目なら、登録時に空白を正規化する、正規化済みの列を別に持つ、計算列を検討するなど、検索時に毎回関数をかけない設計も選択肢です。

normalized-column-example.sql
ALTER TABLE dbo.Customers
ADD CustomerNameNormalized AS TRIM(CustomerName) PERSISTED;

CREATE INDEX IX_Customers_CustomerNameNormalized
ON dbo.Customers (CustomerNameNormalized);

関数を使った条件でインデックスが使われない問題は、SQL Serverでインデックスが使われない原因でも詳しく整理しています。実行計画で確認する場合は、SQL Serverの実行計画の見方も参考になります。

NULLを含む列での注意

TRIM(NULL)REPLACE(NULL, ' ', '')の結果はNULLです。空文字にしたい場合はCOALESCEを使います。

trim-null-handling.sql
SELECT
    TRIM(NULL) AS trim_null,
    COALESCE(TRIM(NULL), N'') AS trim_null_to_empty;

ただし、NULLと空文字は意味が違います。未入力をNULLで管理している設計なら、安易に空文字へ変換しないようにします。

空白削除でよくある失敗

失敗 原因 対策
全角スペースが残る 半角スペースだけを削除している NCHAR(12288)も対象にする
文字列中の空白が残る TRIMは前後だけを削除する REPLACEを使う
検索が遅くなる WHERE句で列に関数をかけている 正規化済み列や計算列を検討する
UPDATEでログが膨らむ 全件を一度に更新している 対象確認後、小分け更新する
NULLが空文字にならない 関数結果がNULLのまま 必要な場合だけCOALESCEを使う

実務で使いやすいクリーニング例

半角スペース、全角スペース、タブ、改行をまとめて除去する例です。取り込みデータのコード値や電話番号など、空白が意味を持たない列で使います。

cleanup-code-value.sql
SELECT
    REPLACE(
        REPLACE(
            REPLACE(
                REPLACE(
                    REPLACE(CodeValue, N' ', N''),
                    NCHAR(12288),
                    N''
                ),
                CHAR(9),
                ''
            ),
            CHAR(13),
            ''
        ),
        CHAR(10),
        ''
    ) AS cleaned_code
FROM dbo.ImportRows;

このような処理は便利ですが、毎回SELECTで行うより、取り込み時に正規化して保存したほうが検索や集計は安定しやすいです。

汎用SQLとしての空白削除は、SQLのスペース削除方法でも扱っています。SQL Serverで検索性能まで見る場合は、カバリングインデックスも合わせて確認するとよいです。

よくある質問

TRIMで全角スペースは削除できますか?

既定のTRIMは半角スペースを対象にするため、全角スペースは残ることがあります。全角スペースを確実に消したい場合はREPLACE(col, NCHAR(12288), N'')を使います。

SQL Server 2016でTRIMは使えますか?

SQL Server 2016ではTRIMではなく、LTRIM(RTRIM(col))を使うのが一般的です。

タブや改行もTRIMで消せますか?

前後にある特定文字の削除はSQL Server 2022以降の拡張構文で対応できる場合がありますが、文字列中も含めて消すならREPLACECHAR(9)CHAR(13)CHAR(10)を対象にするほうが分かりやすいです。

空白削除した値で検索すると遅くなりますか?

WHERE TRIM(col) = ...のように列へ関数をかけると、インデックスが使われにくくなることがあります。頻繁に検索するなら、保存時に正規化するか、正規化済み列を用意します。

REPLACEで空白を消してもNULLが残ります

入力がNULLの場合、REPLACEの結果もNULLです。必要であればCOALESCE(REPLACE(col, ' ', ''), '')のように扱います。

参考

TRIM (Transact-SQL) – Microsoft Learn

LTRIM (Transact-SQL) – Microsoft Learn

RTRIM (Transact-SQL) – Microsoft Learn

REPLACE (Transact-SQL) – Microsoft Learn

まとめ

SQL Serverで前後の空白を削除するならTRIM、古い環境ではLTRIM(RTRIM(...))を使います。文字列中の空白や全角スペース、タブ、改行まで消したい場合はREPLACEを使います。

検索条件や大量UPDATEで空白削除を使う場合は、性能とロックにも注意が必要です。その場で関数をかけるだけでなく、登録時の正規化や正規化済み列の用意も含めて設計しましょう。