Home Functions REPLACE()
SQL String Function

REPLACE()

REPLACE() is a string function that returns a copy of a value in which every occurrence of one substring has been replaced by another, which makes it the standard tool for cleaning and reformatting text.

MySQLPostgreSQLSQL ServerSQLite
Returns: A new string in which every occurrence of the search substring has been swapped for the replacement. The original string is returned unchanged when the search substring is not present, and most engines return NULL when any argument is NULL.

Syntax

REPLACE(string, from_substring, to_substring)REPLACE(column, ' ', '')REPLACE(REPLACE(column, 'a', 'b'), 'c', 'd')UPDATE t SET col = REPLACE(col, from_substring, to_substring)
ParameterTypeRequiredDescription
string string or column yes The source value that is scanned. It can be a literal, a column, or any expression that yields text.
from_substring string yes The substring to look for. Every occurrence is replaced, not only the first one.
to_substring string yes The text that each occurrence is swapped for. Pass an empty string to delete the search substring outright.

How it works

REPLACE() takes three arguments: the text to work on, the substring to find, and the substring to put in its place. It walks the whole value and swaps every match, then hands back a brand new string. The stored data is never touched unless you wrap the call in an UPDATE, so a plain SELECT REPLACE(...) is completely safe to experiment with.

The most common jobs are stripping unwanted characters and changing delimiters. Passing an empty string as the third argument deletes the search text, so REPLACE(phone, ' ', '') removes every space. Passing a different delimiter reformats a value, so you can turn a value that uses one separator into one that uses another. It pairs well with SUBSTRING() when you need to change text by position rather than by content.

On MySQL, SQL Server, and SQLite the match is case sensitive by default, so REPLACE('Hello', 'h', 'J') leaves the value untouched because the capital H does not match a lowercase h. PostgreSQL behaves the same way. When you only want to clean the two ends of a value rather than its interior, reach for TRIM() instead, and browse the full SQL functions library for related tools.

Examples

Remove all spaces from a value

/* an empty replacement deletes every space */
SELECT REPLACE('  John  Smith  ', ' ', '') AS cleaned;
Result
cleaned
=========
JohnSmith

Swap one delimiter for another

/* reformat a phone number by swapping - for / */
SELECT REPLACE('971-50-123-4567', '-', '/') AS reformatted;
Result
reformatted
===============
971/50/123/4567

Mask part of a string

/* hide a known email domain behind stars */
SELECT email,
       REPLACE(email, '@example.com', '@*****.com') AS masked
FROM users;
Result
email             | masked
==================+==================
sara@example.com  | sara@*****.com
omar@example.com  | omar@*****.com

Chain REPLACE calls to strip several characters

/* peel away spaces, dots, and slashes in one pass */
SELECT REPLACE(REPLACE(REPLACE('971 50.123/4567', ' ', ''), '.', ''), '/', '') AS digits_only;
Result
digits_only
============
971501234567

Fix stored data with an UPDATE

/* turn every space in a code into an underscore */
UPDATE products
SET sku = REPLACE(sku, ' ', '_')
WHERE sku LIKE '% %';
Result
sku (before)  | sku (after)
==============+=============
AB 100 X      | AB_100_X
CD 200 Y      | CD_200_Y

Delete a fixed prefix from every value

/* drop the leading protocol from stored urls */
SELECT REPLACE(url, 'https://', '') AS host_path
FROM links;
Result
host_path
======================
codewithsql.com/blog
codewithsql.com/learn

Common mistakes

Wrong
/* you expected only the first space to change,
   but REPLACE swaps every one of them */
SELECT REPLACE('a b c', ' ', '_');
Right
/* REPLACE always changes every match. If you truly
   need only the first one, split the value with
   SUBSTRING and reassemble it, or use a regex
   function such as REGEXP_REPLACE with a limit. */
SELECT REPLACE('a b c', ' ', '_') AS every_match;  /* a_b_c */

The number one surprise with REPLACE() is that it is greedy: it replaces all occurrences of the search substring, never just the first. Plain REPLACE has no way to target a single match.

Wrong
/* nothing changes: the capital H does not match */
SELECT REPLACE('Hello World', 'h', 'J');
Right
/* match the exact case, or normalise first */
SELECT REPLACE('Hello World', 'H', 'J') AS fixed;  /* Jello World */

/* case insensitive: fold the value first */
SELECT REPLACE(LOWER('Hello'), 'h', 'j');

On MySQL, PostgreSQL, SQL Server, and SQLite the search is case sensitive by default. If you need a case insensitive swap, normalise the text with string functions first or use a regex based replace.

Wrong
/* trying to trim outer spaces, but this also
   destroys the space between the words */
SELECT REPLACE('  hi there  ', ' ', '');
Right
/* TRIM removes only the leading and trailing
   characters and leaves the interior intact */
SELECT TRIM('  hi there  ') AS trimmed;  /* hi there */

Use TRIM() when you only want to clean the two ends of a value. REPLACE touches the whole string, so it will happily strip spaces that sit between words as well.

Performance

REPLACE() runs once per row and reads the whole value each time, so on a normal SELECT it is inexpensive. The cost only becomes noticeable when you wrap it around a column inside a WHERE clause, because that hides the raw column from the optimiser and forces a full scan. If you frequently filter on a cleaned form of a value, store the cleaned form in its own column or in a generated column instead of computing it on every query.

Chaining several REPLACE() calls is fine for a handful of characters, but each layer adds another pass over the string. When you need to strip or translate many single characters at once, PostgreSQL and Oracle offer TRANSLATE(), which maps a whole set of characters in one call and is easier to read than a deep nest of replaces.

Bulk cleanups with an UPDATE ... SET col = REPLACE(col, ...) rewrite every matching row and generate write ahead log, so run them in batches on large tables and add a WHERE that skips rows already in the target shape. See the indexing guide for why filtering on a function result cannot use an ordinary index.

Interview questions

What does the SQL REPLACE function do, and how many matches does it change?

REPLACE(string, from, to) returns a copy of the first argument in which every occurrence of the from substring has been swapped for the to substring. It is greedy: it always replaces all matches, never just the first one.

Is REPLACE case sensitive?

Yes, by default on MySQL, PostgreSQL, SQL Server, and SQLite the search substring must match the exact case in the source. To do a case insensitive replace you normalise the text first, for example with LOWER, or you use a regular expression based replace function.

How do you remove every space from a column with REPLACE?

Pass an empty string as the replacement: REPLACE(column, ' ', ''). An empty third argument means each match is deleted rather than swapped, so all spaces disappear.

SELECT REPLACE(product_code, ' ', '') AS cleaned
FROM products;

What is the difference between REPLACE and TRIM?

TRIM() only removes characters from the two ends of a value, while REPLACE swaps a substring wherever it appears in the whole string. Use TRIM to clean leading and trailing padding, and REPLACE to change or delete content in the interior.

How would you replace several different substrings in one query?

Nest the calls so each REPLACE feeds the next, for example REPLACE(REPLACE(col, 'a', 'b'), 'c', 'd'). When you need to map many single characters at once, PostgreSQL and Oracle offer TRANSLATE(), which handles a whole set in a single call.

SELECT REPLACE(REPLACE(phone, ' ', ''), '.', '') AS digits
FROM contacts;

Master SQL, one function at a time

Browse the full SQL functions library, or learn the fundamentals with our free, structured courses.