2.

MySQLのREPLACE関数|文字列置換の使い方とUPDATE例

編集
この記事の要点
  • REPLACE(str, from, to) は文字列 str の中の from をすべて to に置き換えて返す文字列関数。
  • テーブルを書き換えたいときは UPDATE 表 SET 列 = REPLACE(列, '旧', '新') の形で一括置換する。
  • 検索する文字列(from)の照合は大文字小文字を区別する挙動が基本(バイト単位の比較)。
  • 文字列関数の REPLACE() と、行を挿入/置換するSQL文の REPLACE INTOまったくの別物
  • 正規表現で置換したいときは REGEXP_REPLACE()(MySQL 8.0以降/MariaDB 10.0.5以降)を使う。

MySQL/MariaDB の REPLACE() 関数は、ある文字列の中に含まれる特定の部分文字列を、別の文字列へ一括で置き換えて返す文字列関数である。引数は REPLACE(対象, 検索, 置換後) の3つで、対象の中に検索文字列が出現するすべての箇所が置換後の文字列に変わる。

基本構文と動作

構文は次のとおり。引数はすべて文字列式である。

REPLACE(str, from_str, to_str)

動作を確認するには、テーブルを使わずに SELECT でそのまま試すのが手軽である。

SELECT REPLACE('2026-06-12', '-', '/');

-- 結果: 2026/06/12

検索文字列が複数回現れる場合は、そのすべてが置換される。出現しなければ、元の文字列がそのまま返る。

SELECT REPLACE('a-b-c-d', '-', '_');

-- 結果: a_b_c_d(3か所すべて置換)

置換後の文字列に空文字 '' を指定すると、検索文字列を取り除く(削除する)用途にも使える。

SELECT REPLACE('090-1234-5678', '-', '');

-- 結果: 09012345678(ハイフン除去)

UPDATE で列の値を一括置換する

テーブルに保存済みのデータをまとめて書き換えるには、UPDATE 文の SET 句で REPLACE() を使う。たとえば url 列に含まれる http:// をすべて https:// に変えるには次のようにする。

UPDATE pages

SET url = REPLACE(url, 'http://', 'https://')

WHERE url LIKE 'http://%';

ポイントは SET url = REPLACE(url, ...) のように列自身を第1引数に渡すこと。これで「いまの値を置換した結果」で同じ列を上書きする。WHERE 句は必須ではないが、対象行を絞ることで無駄な更新を避けられる(検索文字列を含まない行は REPLACE() しても値が変わらないため、付けなくても結果は同じだが、更新行数を抑えられる)。

大文字小文字の区別に注意

第2引数(検索文字列)の照合は、バイト単位での比較となり大文字小文字を区別する。つまり 'ABC' を検索しても 'abc' はヒットしない。

SELECT REPLACE('Apple apple', 'apple', 'orange');

-- 結果: Apple orange(先頭の Apple は置換されない)

これは列の照合順序(collation)が大文字小文字を区別しない(_ci)設定であっても変わらない。WHERE 句の LIKE 比較とは挙動が異なる点に注意したい。大文字小文字をまとめて置換したい場合は、REGEXP_REPLACE()i オプション(後述)などを検討する。

REPLACE() 関数と REPLACE INTO 文は別物

混同しやすい落とし穴
同じ「REPLACE」という名前だが、文字列関数の REPLACE()SQL文の REPLACE INTO はまったくの別機能である。後者は INSERT に似た構文で、主キー(または一意キー)が重複する行があれば既存行を削除してから挿入し直す文であり、文字列の置換とは無関係。検索して見つけたサンプルがどちらの話か取り違えないよう注意する。

-- 文字列の一部を置き換える(文字列関数)

SELECT REPLACE('foo', 'o', '0');

 

-- 行ごと挿入し直す(SQL文・置換とは無関係)

REPLACE INTO users (id, name) VALUES (1, 'Sato');

REGEXP_REPLACE() との違い

REPLACE() は固定文字列のみを対象とする単純置換であり、「数字だけ」「空白の連続」といったパターン指定はできない。正規表現で柔軟に置換したい場合は REGEXP_REPLACE() を使う。ただし利用できるバージョンが限られる(2026年時点では一般に利用可能)。

項目 REPLACE() REGEXP_REPLACE()
検索対象 固定の部分文字列 正規表現パターン
大文字小文字 常に区別する オプションで制御可(i など)
利用可能バージョン すべての版で利用可 MySQL 8.0以降/MariaDB 10.0.5以降
単純な置き換え こちらが簡潔・高速 過剰
パターン置換 不可 こちらを使う

-- 連続する空白を1つにまとめる(正規表現が必要な例)

SELECT REGEXP_REPLACE('a   b', ' +', ' ');

-- 結果: a b

よくある質問

Q. 置換対象が NULL のときはどうなりますか?

A. REPLACE() はいずれかの引数が NULL の場合、結果も NULL を返す。たとえば REPLACE(NULL, 'a', 'b')NULL になる。UPDATENULL の行を残したくない場合は WHERE 列 IS NOT NULL を併用するか、IFNULL() などで補う。

Q. 1回の REPLACE() で複数種類の文字を置き換えられますか?

A. 1回の呼び出しでは1種類の検索文字列しか扱えない。複数種類を置き換えたいときは REPLACE() を入れ子(ネスト)にする。たとえば REPLACE(REPLACE(col, 'a', 'x'), 'b', 'y') のように内側から順に適用される。

Q. 置換できたか件数を確認したいです。

A. UPDATE 実行後にクライアントが返す影響行数(affected rows)で更新された行の数がわかる。ただし、置換前後で値が同じだった行はカウントに含まれないことがある。事前確認したい場合は、同じ条件で SELECT REPLACE(col, '旧', '新') FROM 表 WHERE ... を実行して結果を見てから UPDATE するとよい。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. 現在日時の取得
  2. replaceによる文字列置換

最近更新/作成されたページ