Home Functions REVERSE()
SQL String Function

REVERSE()

REVERSE() is a string function that returns its argument with the characters written from last to first.

MySQLPostgreSQLSQL Server
Returns: A string containing the same characters as the input but in the opposite order. Returns NULL when the input is NULL.

Syntax

REVERSE(string_expression)
ParameterTypeRequiredDescription
string_expression string or expression yes The value whose characters are returned in reverse order. Non string values are usually cast to text first.

How it works

REVERSE() takes a single string and returns a new string with the characters in the opposite order, so REVERSE('SQL') yields LQS. It does not change the original data; like every scalar string function it produces a value you can select, filter on, or nest inside another expression.

The classic practical use is pulling out the part of a string that comes after the last occurrence of a delimiter. Functions such as POSITION() find the first match from the left, so to work from the right you reverse the string, find the delimiter near the front, then reverse the answer back. This is the standard trick for grabbing a file extension after the final dot or the last segment of a path.

REVERSE() is also a compact way to test for palindromes: a value reads the same forwards and backwards when it equals its own reverse. One important portability note is that SQLite has no built in REVERSE() function, so code that relies on it will not run there without a user defined function.

Examples

Reverse a simple string

SELECT REVERSE('database') AS reversed;
Result
reversed
========
esabatad

Reverse a column value

SELECT name, REVERSE(name) AS backwards
FROM products;
Result
name   | backwards
=======+==========
apple  | elppa
mango  | ognam
lemon  | nomel

Get the file extension after the last dot

-- Reverse, find the first dot from the front (the last
-- dot in the original), take what is before it, reverse back
SELECT filename,
       REVERSE(SUBSTRING(REVERSE(filename), 1,
               POSITION('.' IN REVERSE(filename)) - 1)) AS ext
FROM documents;
Result
filename       | ext
===============+=====
report.final.pdf | pdf
archive.tar.gz   | gz
notes.txt        | txt

Palindrome check

SELECT word,
       CASE WHEN word = REVERSE(word)
            THEN 'yes' ELSE 'no' END AS is_palindrome
FROM words;
Result
word  | is_palindrome
======+==============
level | yes
radar | yes
hello | no

Sort by the end of a string

-- Order emails by their reversed form to group
-- similar domains and suffixes together
SELECT email
FROM users
ORDER BY REVERSE(email);
Result
email
==================
sam@abbaz.com
lee@codewithsql.com
zoe@codewithsql.com

Common mistakes

Wrong
-- On a byte oriented charset, some engines reverse
-- by byte and split a multibyte character (an emoji
-- or an accented letter) into invalid fragments
SELECT REVERSE(nickname) FROM users;
Right
-- Store the text as UTF8 and use a matching collation
-- so REVERSE works on whole characters, not raw bytes
SELECT REVERSE(CONVERT(nickname USING utf8mb4)) FROM users;

REVERSE operates on characters, but only if the engine knows the encoding. With a byte oriented charset a multibyte character can be split into invalid fragments. Store text as UTF8 and use a matching collation so each character is reversed as a unit.

Wrong
-- Fails on SQLite: no such function REVERSE
SELECT REVERSE(name) FROM products;
Right
-- SQLite has no REVERSE. Register a user defined
-- function in your application, or avoid REVERSE and
-- use a portable approach for the same result.
SELECT name FROM products;  -- reverse in application code

Do not assume REVERSE() exists everywhere. MySQL, PostgreSQL and SQL Server ship it, but SQLite does not. Portable code should feature detect or use a user defined function.

Performance

REVERSE() is a cheap per row operation, but wrapping a column in it inside a WHERE clause makes the predicate non sargable: the database cannot use a normal index on the raw column and falls back to a full scan. If you frequently query by the end of a string, store a reversed copy in a persisted or generated column and index that instead.

The extension and last segment trick that nests REVERSE() around SUBSTRING() and POSITION() runs three function calls per row. That is fine for projection, but avoid it in filters over large tables. Precompute the derived value once when you can rather than recomputing it on every scan.

Interview questions

What does the SQL REVERSE() function do?

It returns its string argument with the characters in the opposite order, so REVERSE('abc') returns cba. It returns NULL for a NULL input and does not modify the stored data.

How would you extract the file extension after the last dot?

Reverse the string so the last dot becomes the first, use POSITION() to find that dot, take the characters before it with SUBSTRING(), then reverse the result back to normal order.

SELECT REVERSE(SUBSTRING(REVERSE(filename), 1,
       POSITION('.' IN REVERSE(filename)) - 1)) AS ext
FROM documents;

How can REVERSE() help detect a palindrome?

A value is a palindrome when it equals its own reverse, so you compare the column with REVERSE(column). If they match the text reads the same forwards and backwards.

SELECT word
FROM words
WHERE word = REVERSE(word);

Which common database lacks a built in REVERSE() function?

SQLite. MySQL, PostgreSQL and SQL Server all provide REVERSE(), but on SQLite you must register a user defined function or handle the reversal in application code.

Why can using REVERSE() in a WHERE clause hurt performance?

Applying a function to a column makes the predicate non sargable, so the optimiser cannot use an ordinary index on that column and must scan the table. Indexing a stored reversed copy of the column restores index usage.

Master SQL, one function at a time

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