Guides

SQL REVERSE: How to Reverse a String in Your Database

Learn SQL REVERSE in SQL Server, MySQL, and PostgreSQL, with read-only examples, Unicode cautions, and a practical filename-extension query.

By Text Reverser TeamOctober 26, 20268 min read

A database column can contain a filename, a code, a token, a word, or a complete sentence. Sometimes you need the same value with its characters in the opposite order. That is what the SQL REVERSE function does: it returns a transformed value; it does not change the stored row by itself.

This distinction matters because “reverse” can describe three different jobs:

  • Reverse characters: stressed becomes desserts.
  • Reverse word order: red green blue becomes blue green red, while each word keeps its spelling.
  • Reverse sort direction: ORDER BY created_at DESC shows later rows first. It does not reverse text.

This guide concentrates on character reversal in SQL Server, MySQL, and PostgreSQL, then applies it to a useful SQL Server filename task. Every example is read-only: it uses SELECT and common table expressions (CTEs), not UPDATE, DELETE, or table creation.

The basic SQL REVERSE function

The smallest useful example is:

SELECT REVERSE('stressed') AS reversed_text;

Expected result:

reversed_text
-------------
desserts

For a column, put the column expression inside the function and keep the original value visible while testing. This example assumes an existing products table with a text column named product_code:

SELECT
    product_code,
    REVERSE(product_code) AS reversed_product_code
FROM products;

The result is a new expression in the query output. It is not an encryption method, a hash, or a security control. Reversal is deterministic and easy to undo, so do not use it to protect secrets.

For a quick smoke test, start with a literal before introducing a table column. Then test a representative row beside its transformed value. This makes it easier to distinguish a function problem from a data-quality problem such as an unexpected trailing space, a NULL, or a delimiter that is not actually present. Keep the test as a SELECT while you inspect the result; only a separate, explicitly reviewed write operation should change stored data.

SQL Server, MySQL, and PostgreSQL syntax

SQL Server (T-SQL)

SQL Server uses REVERSE(string_expression) and returns a character value. Microsoft documents it as returning the reverse order of a string value; the input may be a string or binary type and must be implicitly convertible to varchar where required (Microsoft Learn: REVERSE). In normal text work, make the intended type explicit when a mixed or unusual expression could otherwise be ambiguous:

SELECT REVERSE(CAST('abc123' AS varchar(20))) AS reversed_text;

NULL stays NULL, so a missing value is not silently turned into a word. An empty string returns an empty string. Those cases are different from a string containing spaces, and the difference can matter in validation or reporting.

Under supplementary-character (SC) collations, SQL Server’s REVERSE does not split the two halves of a UTF-16 surrogate pair. That is safer than blindly swapping code units, but it is not a promise that every user-perceived grapheme cluster—such as a base character combined with marks or an emoji sequence joined by zero-width joiners—will remain visually meaningful when reversed. Use an N-prefixed string literal when supplying Unicode text as an nvarchar literal in T-SQL.

MySQL

MySQL uses the same spelling:

SELECT REVERSE('stressed') AS reversed_text;

The MySQL reference says REVERSE(str) returns characters in reverse order, returns NULL when str is NULL, and is multibyte safe (MySQL 8.4 Reference Manual: String Functions). “Multibyte safe” means the function does not confuse the bytes of an ordinary multibyte character with separate characters. It does not mean that every grapheme cluster or display sequence is handled according to a user’s visual expectations. Binary strings and ordinary text strings also have different character-set semantics, so confirm the actual column type.

PostgreSQL

PostgreSQL also provides a native function:

SELECT reverse('stressed') AS reversed_text;

Its documented signature is reverse(text), which reverses the order of characters (PostgreSQL documentation: String Functions). With text in a supported database encoding, think in characters rather than raw storage bytes. As with the other systems, character reversal is not the same as grapheme-aware typography.

What about SQLite and Oracle?

Do not copy a three-engine example into every database and assume portability. SQLite’s official core-function list does not include a built-in REVERSE; an application-defined function, extension, or a different query approach is needed. The available option depends on the SQLite host and deployment. Oracle users should consult their release’s documented string functions: the examples here are not Oracle SQL and should not be assumed to work unchanged.

What REVERSE does not do

A function call cannot infer which kind of reversal you meant. For word order, you need tokenization, a definition of whitespace, and an aggregation strategy. For sorting, use an explicit ordering expression. Assuming an orders table with these columns:

SELECT order_id, created_at
FROM orders
ORDER BY created_at DESC, order_id DESC;

That changes row order only. It does not modify created_at, order_id, or any text value. The secondary sort makes ties deterministic if order_id is unique. Without an ORDER BY, do not rely on a particular result-row order.

Conversely, this query against an existing notes table changes the displayed character sequence but does not request a particular row order:

SELECT note, REVERSE(note) AS reversed_note
FROM notes;

Keeping those jobs separate prevents a common bug: applying DESC when the requirement was to reverse a code, or applying REVERSE when the requirement was simply “newest first.”

Practical SQL Server example: extract the final filename extension

A useful reason to understand reversal is finding the text after the last delimiter. A filename may contain several dots, so searching from the left finds the wrong one. Reverse the filename, find the first dot in that reversed value, then take the corresponding rightmost characters from the original. No stored data needs to change.

The following self-contained T-SQL CTE includes multiple dots, no dot, a final dot, an empty string, and NULL. The sample numbers preserve a predictable output order:

;WITH source_files (sample_id, file_name) AS (
    SELECT sample_id, CAST(v AS nvarchar(100))
    FROM (VALUES
        (1, N'report.final.csv'),
        (2, N'README'),
        (3, N'archive.tar.gz'),
        (4, N''),
        (5, NULL),
        (6, N'file.')
    ) AS sample(sample_id, v)
), marked AS (
    SELECT
        sample_id,
        file_name,
        CHARINDEX(N'.', REVERSE(file_name)) AS reverse_dot_position
    FROM source_files
)
SELECT
    file_name,
    CASE
        WHEN file_name IS NULL THEN NULL
        WHEN reverse_dot_position = 0 THEN NULL
        ELSE RIGHT(file_name, reverse_dot_position - 1)
    END AS extension_text
FROM marked
ORDER BY sample_id;

The intended output is:

file_name          extension_text
-----------------  --------------
report.final.csv   csv
README             NULL
archive.tar.gz     gz
(empty string)     NULL
NULL               NULL
file.              (empty string)

This policy says “no dot means NULL.” A final dot is different: file. has a delimiter but no characters after it, so RIGHT(file_name, 0) produces an empty string. If your business rule wants a final dot treated as missing instead, add an explicit condition rather than leaving the behavior accidental. The displayed NULL entries represent SQL null values, not the literal four-letter string.

There are several details worth preserving in this pattern:

  1. CHARINDEX searches for the first occurrence in the value it receives. Because the value is reversed, that first occurrence corresponds to the original string’s final dot. SQL Server positions are 1-based, and CHARINDEX returns 0 when it finds no match (Microsoft Learn: CHARINDEX).
  2. The NULL branch is explicit. A missing filename should remain NULL, not be mistaken for a no-extension empty value.
  3. The CTE is not just cosmetic. The alias reverse_dot_position is created in one query stage and consumed in the next; SQL Server does not generally allow a select-list alias to be referenced by another expression in that same select list.
  4. The example uses RIGHT with the original filename. It does not return the reversed suffix; it uses reversal only to locate the final delimiter.

This is a delimiter demonstration, not a complete filesystem parser. A dot in a directory name, a hidden-file naming convention, or an extension policy that treats tar.gz as one unit needs additional rules. Feed the query a filename component rather than an arbitrary full path unless you have explicitly handled path separators.

A trailing-space warning

Do not casually replace the staged expression with arithmetic based on LEN(file_name) when exact trailing spaces matter. SQL Server’s LEN excludes trailing spaces; Microsoft points to DATALENGTH when the byte count including trailing spaces is needed (Microsoft Learn: LEN). Byte counts are not interchangeable with character counts, especially for Unicode.

The example avoids LEN entirely, so its delimiter position is not based on a length that silently drops trailing spaces. You should still define whether spaces around a filename are valid data and test that rule separately.

NULL, empty strings, spaces, and punctuation

Before putting REVERSE into a view, report, or computed expression, decide what each input class should mean:

  • REVERSE(NULL) is NULL in SQL Server, MySQL, and PostgreSQL.
  • REVERSE('') is an empty string, not the same thing as NULL.
  • Spaces are characters. REVERSE(' ab ') returns ' ba ', moving spaces to the opposite ends without trimming them.
  • Punctuation is also reversed. REVERSE('a-b/c.') returns '.c/b-a'.
  • Combining marks, emoji sequences, and other multi-code-point display units need application-level testing if visual text quality matters.

A query that is correct for ASCII identifiers may not be correct for human language. Test the actual collation, character set, encoding, and client display path used by your application. SQL Server’s SC-collation rule, MySQL’s multibyte-safe guarantee, and PostgreSQL’s text-character semantics are useful protections, but none is a universal grapheme-cluster reversal specification.

Performance: a display expression is not an index strategy

Using REVERSE in a small result set is straightforward. Applying it to every value in a large filter, sort, or join deserves a query-plan review. An ordinary index on the original column does not automatically become an index on the reversed expression. Whether an expression index or indexed computed column can help depends on the engine, query shape, and configuration.

For example, do not add reversal to a suffix search merely because it makes the condition look like a prefix search. A useful optimization would need an appropriately indexed representation and a matching predicate; changing the expression alone is not a performance guarantee. Measure on representative data and inspect the execution plan before changing schema or adding indexes.

For reporting, return only the rows and columns you actually need. Keep the original and derived values together during validation, then decide whether downstream consumers need both. A CTE makes the logic readable, but does not by itself guarantee that the engine materializes a result or computes an expression only once.

A practical validation checklist

Before shipping a query that uses SQL REVERSE, check the following:

  • Is the requirement character reversal, word-order reversal, or descending sort?
  • Which engine and version will execute it?
  • Are NULL, empty strings, whitespace-only values, and punctuation covered by tests?
  • If extracting a suffix, have you tested no delimiter, one delimiter, multiple delimiters, and a final delimiter?
  • Does the output preserve the source column while you validate it?
  • Have representative Unicode examples been checked under the production collation or encoding?
  • Is the expression being used for transformation rather than as a security mechanism?

For text outside the database, Text Reverser can help you inspect a sample quickly. The site’s reverse line order guide addresses a different operation: moving complete lines rather than reversing characters inside each value.

Final takeaway

REVERSE is a small, clear function when the requirement really is “return these characters in the opposite order.” SQL Server, MySQL, and PostgreSQL expose it directly, with broadly similar null behavior and important Unicode qualifications. Use a separate query stage when derived positions feed later expressions, keep delimiter policies explicit, and preserve the original column while validating. Once character reversal is separated from word order and ORDER BY ... DESC, the query says exactly what it does.

Try the Text Reverser tool

Reverse text, words, or letters instantly — free and entirely in your browser.

Open the tool

Permalink: https://www.textreverser.me/blog/sql-reverse-string