Home Functions LOWER()
SQL String Function

LOWER()

LOWER() is a string function that converts every letter in a value to lower case. It is used to normalise emails and usernames and to make comparisons case insensitive.

MySQLPostgreSQLSQL ServerSQLite
Returns: A string with every alphabetic character converted to lower case. Returns NULL when the input is NULL.

Syntax

LOWER(string)LCASE(string)
ParameterTypeRequiredDescription
string string expression yes The text value, column or expression to convert. Digits, spaces and punctuation are returned unchanged; only letters are folded to lower case.

How it works

LOWER() takes a single string and returns a copy of it with all alphabetic characters folded to lower case. Non letter characters such as numbers, spaces and symbols pass through untouched, so LOWER('Order #42B') gives order #42b. Its counterpart is UPPER(), which does the reverse.

In MySQL the name LCASE() is an alias for LOWER(): the two behave identically, and LOWER() is the portable choice because it is the SQL standard name understood by PostgreSQL, SQL Server and SQLite as well. Prefer LOWER() in code you may move between engines.

The most common use is normalisation. Emails and usernames are usually meant to be case insensitive, so folding both sides of a comparison with LOWER() lets John.Doe@Shop.com match john.doe@shop.com. Many teams also store the value already lowered so lookups stay simple. Browse the full SQL functions library for related text helpers such as TRIM().

Examples

Lowercase a column

SELECT username, LOWER(username) AS username_lower
FROM users;
Result
username | username_lower
=========+===============
JohnDoe  | johndoe
MaryJane | maryjane
BOBSMITH | bobsmith

Normalise emails before comparing

SELECT id, email
FROM customers
WHERE LOWER(email) = LOWER('John.Doe@Shop.com');
Result
id | email
===+==================
 7 | john.doe@shop.com

Store the normalised value on insert

INSERT INTO customers (email)
VALUES (LOWER('Sara.Ali@Mail.COM'));

SELECT email FROM customers WHERE id = LAST_INSERT_ID();
Result
email
================
sara.ali@mail.com

Case insensitive join and filter

SELECT o.id, u.username
FROM orders o
JOIN users u
  ON LOWER(o.user_handle) = LOWER(u.username)
WHERE LOWER(u.username) = 'johndoe';
Result
id | username
===+=========
 3 | JohnDoe
 8 | JohnDoe

LCASE alias in MySQL

SELECT LCASE('HELLO World') AS lowered;
Result
lowered
===========
hello world

Common mistakes

Wrong
/* email is indexed, but wrapping it in LOWER()
   forces a full scan of every row */
SELECT * FROM customers
WHERE LOWER(email) = 'john@shop.com';
Right
/* PostgreSQL: index the expression itself so the
   lookup can still use an index only scan */
CREATE INDEX idx_customers_email_lower
  ON customers (LOWER(email));

SELECT * FROM customers
WHERE LOWER(email) = 'john@shop.com';

Calling LOWER() on an indexed column inside WHERE hides the column from the optimiser, so a plain index cannot be used and the query scans the table. Fix it with a functional index on LOWER(email), or store the column with a case insensitive collation so no function is needed. See the indexing guide for why this happens.

Wrong
/* Expecting this to lower case the stored data.
   It does not: the users table still holds the
   original mixed case values. */
SELECT LOWER(username) FROM users;
Right
/* LOWER() returns a new value; to change what is
   stored you must write it back with UPDATE. */
UPDATE users
SET username = LOWER(username);

LOWER() never modifies the underlying rows. A SELECT only transforms the result set. Use UPDATE ... SET col = LOWER(col) when you actually want to change the stored data.

Performance

Applying LOWER() to a value in the SELECT list is cheap. The cost appears when you wrap an indexed column in it inside WHERE or JOIN, because the database can no longer match the plain index and falls back to scanning every row.

Two fixes keep such queries fast. The first is a functional index on the expression, for example CREATE INDEX ... ON customers (LOWER(email)), supported by PostgreSQL, SQLite and SQL Server (through a computed column). The second is a case insensitive collation on the column, which lets the engine compare values without any function call at all.

If you compare a column against constants often, storing the value already lowered is usually simplest: normalise once on insert, then compare directly against a plain index. Read the indexing guide for how an index only scan avoids touching the base table.

Interview questions

What does LOWER() do, and how does it differ from LCASE()?

LOWER() converts every letter in a string to lower case and leaves digits, spaces and punctuation unchanged. LCASE() is a MySQL alias that behaves identically. LOWER() is the SQL standard name and works across MySQL, PostgreSQL, SQL Server and SQLite, so it is the portable choice.

How do you perform a case insensitive comparison in SQL?

Fold both sides to the same case, for example WHERE LOWER(email) = LOWER(:input). Alternatively use a case insensitive collation on the column so no function is needed. Folding both sides is portable; a collation is often faster because it can still use an index.

SELECT id FROM customers
WHERE LOWER(email) = LOWER('John@Shop.com');

Does LOWER() change the data stored in the table?

No. LOWER() returns a transformed copy of the value in the result set only. To change what is stored you must run an UPDATE, such as UPDATE users SET username = LOWER(username).

Why can LOWER() on a column slow down a query, and how do you fix it?

Wrapping an indexed column in LOWER() inside WHERE stops the optimiser from using the plain index, forcing a full scan. Fix it with a functional index on LOWER(column) or a case insensitive collation, or store the value already lowered.

What does LOWER() return when the input is NULL?

It returns NULL. Like most scalar string functions, LOWER() propagates NULL, so LOWER(NULL) is NULL rather than an empty string.

Master SQL, one function at a time

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